Мета-сервис Angular 6 с динамическими метаданными из веб-сервиса

Я пытаюсь использовать данные, полученные из веб-службы, для обновления метаданных в универсальном приложении Angular 6 (обновление: теперь Angular 7) (с использованием Meta и Title). Я специально делаю это для карт Twitter и Facebook. Я знаю, что их сканеры не выполняют JavaScript, поэтому я использую Angular Universal для установки метаданных на стороне сервера. Я использую инструмент отладчика Facebook Sharing для проверки результатов.

Я пробовал несколько разных подходов и искал примеры, но не нашел ни одного, в котором данные извлекались бы из асинхронного вызова веб-службы до установки метаданных. (Обратите внимание, что я успешно использовал эту службу с веб-службой в приложении Angular Universal 4.)

Используя приведенный ниже код, тег «og:url» установлен правильно, поскольку для получения данных не требуется вызов веб-службы. Тем не менее, заголовок не установлен должным образом. Если я передам вызов setTitle в ngOnInit и предоставлю строку, это сработает, но получение данных из веб-службы не сработает.

Я пытался использовать службу для сбора данных, а затем установить метаданные, но это тоже не работает. Я получаю данные от преобразователя, но это не решает проблему Facebook/Twitter.

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 });
  });

}

Обновление: я также пытался использовать Resolver, чтобы сначала получить данные, чтобы я мог просто использовать их в onInit. Это не работает.

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

Затем в 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 });

person beachCode    schedule 30.09.2018    source источник
comment
Вы проверили, что выполнение кода идет через getInfo серверную часть?   -  person David    schedule 06.10.2018
comment
Да, я проверил страницу, отображаемую сервером, и все в порядке, включая метатеги в источнике. Однако, когда я развертываю приложение в Google App Engine, инструмент отладки Facebook не видит обновленные метатеги. Я даже добавил преобразователь для получения данных первым, и он все еще не работает.   -  person beachCode    schedule 06.10.2018
comment
Что-то должно быть не так с Angular Universal, так как предоставленный код выглядит нормально. AU останавливает рендеринг, когда в ngZone больше нечего делать, может быть, вызов API выполняется за пределами ngZone? Может дело в подключении? Возможно, наблюдаемый вызов API возвращает ошибку, которая может предоставить дополнительную информацию. Сервер AU работает локально? Вы можете легко проверить выходную строку на своем локальном компьютере. :думаю: :думаю:   -  person Mezo Istvan    schedule 29.10.2018
comment
Я согласен с вашей оценкой. Я проверил локально, и страница на стороне сервера верна (т.е. правильные теги есть в источнике). Любое предложение о том, как отлаживать это в рабочей среде? Может быть, мне следует настроить страницу SSR на другой порт и проверить ее таким образом? Спасибо!   -  person beachCode    schedule 29.10.2018
comment
Я бы предложил создать службу, которая внедряется как зависимость от приложения SSR. Так что вы сначала создадите и заполните этот сервис полностью на стороне сервера, а затем передадите все данные render приложения SSR. Трудно контролировать асинхронные вызовы во время рендеринга, поэтому мы обнаружили, что хорошей практикой является предварительное разрешение всех данных и передача их render для как можно меньшего количества дополнительных заданий. Я могу показать вам пример, если все еще интересно.   -  person muradm    schedule 29.10.2018


Ответы (1)


Я нашел решение. Решив, что это не должно быть проблемой кода, я перешел к начальному репозиторию Angular Universal и обновил его. мою конфигурацию (например, tsconfig.json, angular.json и т. д.), пока она не заработает. Мой проект обновлялся несколько раз, и я не скопировал все изменения из стартового репозитория.

person beachCode    schedule 30.10.2018