title: Angular 6 Meta service with dynamic metadata from web service
body: <p>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 <a href="https://developers.facebook.com/tools/debug" rel="noreferrer">Facebook Sharing debugger tool</a> to check the results.</p>
  
  <p>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.)</p>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <pre><code>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 =&gt; {
        const code = params['person'];
        this.getInfo(code);
      });
  }
  
  getInfo(code: string) {
    this._myWebService.getPerson(code).subscribe(
        data =&gt; {
          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 });
    });
  
  }
  </code></pre>
  
  <p>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.</p>
  
  <pre><code> { path: 'view/:person', component: ViewComponent,
      resolve: { person: ViewResolver }, data: { person: ViewResolver }
    }
  </code></pre>
  
  <p>Then in onInit:</p>
  
  <pre><code>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 });
  </code></pre>