Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 6 Meta service with dynamic metadata from web service

I'm trying to use data retrieved from a web service to update the metadata in an Angular 6 (update: now Angular 7) Universal app (using Meta and Title). I'm specifically doing this for Twitter and Facebook cards. I know that their crawlers don't execute JavaScript which is why I use Angular Universal to set the metadata on the server side. I'm using the Facebook Sharing debugger tool to check the results.

I've tried a few different approaches, and I've looked for examples, but I haven't found one where data is retrieved from an async call to a web service before the metadata is set. (Note that I used this service successfully with a web service in an Angular Universal 4 app.)

Using the code below, the "og:url" tag is properly set as that one does not require the web service call to get the data. However, the title is not properly being set. If I move the "setTitle" call to ngOnInit and supply a string, that works--but getting the data from the web service doesn't.

I've tried using a service to collect the data and then set the metadata, but that isn't working either. I get the data from the resolver but it doesn't solve the Facebook/Twitter problem.

ngOnInit() {
    const metaUrl = 'https://www.test.com' + this._router.url;
    this._metaService.updateTag({ property: 'og:url', content: metaUrl });

    this._sub = this._route.params.subscribe(params => {
      const code = params['person'];
      this.getInfo(code);
    });
}

getInfo(code: string) {
  this._myWebService.getPerson(code).subscribe(
      data => {
        this._person = data;
        // set dynamic metadata
        const metaTitle = this._person.name + ' | site description';
        this._titleService.setTitle(metaTitle);
        this._metaService.updateTag({ name: 'twitter:title', content: metaTitle });
  });

}

Update: I also tried using a Resolver to get the data first so that I could just use it in onInit. It's not working.

 { path: 'view/:person', component: ViewComponent,
    resolve: { person: ViewResolver }, data: { person: ViewResolver }
  }

Then in onInit:

const data: any = this._routeActive.snapshot.data;
this.metaTitle = data.person.value.name;
this._metaService.updateTag({property: 'og:title', content: this.metaTitle });
this._metaService.updateTag({name: 'twitter:title', content: this.metaTitle });
like image 249
beachCode Avatar asked Sep 30 '18 08:09

beachCode


1 Answers

I found a solution. After deciding this must not be a code issue, I went to the Angular Universal starter repo and updated my config (e.g., tsconfig.json, angular.json, etc.) until it worked. My project has been upgraded a few times and I hadn't copied over all the changes from the starter repo.

like image 173
beachCode Avatar answered Sep 27 '22 23:09

beachCode