embedded Twitter widget on Angular 2+ app only shows up on the first page load

坚强是说给别人听的谎言 提交于 2019-12-01 01:14:33

Try this, no need to subscribe or timeout.

ngOnInit() {
   (<any>window).twttr.widgets.load();
}

I know this is an old question, but I got a better solution than setting a timeout. The code I posted as solution in this question is broken since late Angular 4 or early Angular 5 - I don't remember. I will update my answer there too.

So, to fix this, just put the code in the constructor (so the widget loads before the view) like so:

import { Component, OnDestroy } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';

@Component({ ... })

export class HomeComponent implements OnDestroy {
  private twitter: any;

  constructor(private _router: Router) {
    this.initTwitterWidget();
  }

  initTwitterWidget() {
    this.twitter = this._router.events.subscribe(val => {
      if (val instanceof NavigationEnd) {
        (<any>window).twttr = (function (d, s, id) {
          let js: any, fjs = d.getElementsByTagName(s)[0],
              t = (<any>window).twttr || {};
          if (d.getElementById(id)) return t;
          js = d.createElement(s);
          js.id = id;
          js.src = "https://platform.twitter.com/widgets.js";
          fjs.parentNode.insertBefore(js, fjs);

          t._e = [];
          t.ready = function (f: any) {
              t._e.push(f);
          };

          return t;
        }(document, "script", "twitter-wjs"));

        if ((<any>window).twttr.ready())
          (<any>window).twttr.widgets.load();

      }
    });
  }

  ngOnDestroy() {
    this.twitter.unsubscribe();
  }
}

If I find any information on why previous code was broken, I'll update this answer. (Or if anyone else knows, feel free to edit this)

Okay, I found a way to work around based on this reference (Why will my twitter widget not render if i change the view in angularjs?). No need for event subscription, I need to wrap the function into setTimeOut to re-render it between route switch. Remember to also wrap the setTimeOut function inside isPlatformBrowser for a better practice of pre-rendering. Here is the code:

import { Component, OnInit, OnDestroy, AfterViewInit, PLATFORM_ID, Inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

constructor(@Inject(PLATFORM_ID) private platformId: Object) { }

ngAfterViewInit() {    
 if (isPlatformBrowser(this.platformId)) {
  setTimeout(function() { 
    (<any>window).twttr = (function(d, s, id) {
      let js, fjs = d.getElementsByTagName(s)[0],
        t = (<any>window).twttr || {};
      if (d.getElementById(id)) return t;
      js = d.createElement(s);
      js.id = id;
      js.src = 'https://platform.twitter.com/widgets.js';
      fjs.parentNode.insertBefore(js, fjs);

      t._e = [];
      t.ready = function(f) {
        t._e.push(f);
      };

      return t;
    }(document, 'script', 'twitter-wjs'));
    (<any>window).twttr.widgets.load(); }, 100);
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!