Ошибка при передаче части наблюдаемого объекта в качестве входа в угловой компонент? - PullRequest
0 голосов
/ 02 ноября 2019

У меня есть вопрос о случае гонки, который я вижу с моим Observable. Вероятно, это скорее общая наблюдаемая / угловая проблема. При переходе с одного маршрута на другой я вижу cannot read 'property' of undefined error от контроллера, который разрушается при переходе на новый маршрут. В моем контроллере у меня есть такой метод:

// this.setting$: Observable<object>;

get name$: Observable<string> {
    return this.settings$.pipe(map(settings => settings.name));
}

Эта функция вызывает ошибку. В том же шаблоне компонентов у меня есть:

<some-component [name]="name$ | async"></some-component>

Когда я перехожу на новую страницу, селектор this.settings$ возвращает неопределенное значение, и код моего контроллера выдает ошибку. Странно то, что мой компонент уже был уничтожен при возникновении ошибки консоли (проверено с помощью ведения журнала консоли ngOnDestroy).

Я нашел два решения, которые решают мою проблему. решение A:

// Parse the name property in the template - which I think looks ugly
<some-component [name]="(settings$ | async).name"></some-component>

Или решение B:

// Pass entire settings object into component and parse out name in some-component controller - yuck
<some-component [settings]="settings$ | async"></some-component>

Мне не нравится ни одно решение. Решение AI не нравится, потому что оно выглядит неуклюже в шаблоне - но, возможно, мне стоит просто разобраться с этим. Решение BI не нравится, потому что это не совсем элегантное решение.

Я не совсем понимаю, почему любое из решений решает проблему. Кто-нибудь может указать, почему существует эта проблема? Особенно учитывая, что компонент был уничтожен. Это похоже на потерянную подписку, но я не понимаю, как.

РЕДАКТИРОВАТЬ: я создал стек, который воспроизводит проблему. https://stackblitz.com/edit/ngxs-repro-ndaco6. Существует три маршрута: / home, / profile, / settings. Параметры / profile и / settings зависят от того, какой идентификатор учетной записи находится в URL. / дома нет. Обратите внимание, что при маршрутизации из / profile в / home консольная ошибка отсутствует. Однако при маршрутизации из / settings в / home возникает ошибка консоли. Может кто-нибудь помочь мне понять, почему? Обратите внимание, что компонент SettingsComponent, который выдает ошибку, уже уничтожен, когда выдается ошибка.

Ответы [ 2 ]

1 голос
/ 02 ноября 2019

Использовать

name$ = this.settings$.pipe(map(settings => settings ? settings.name : null));

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

0 голосов
/ 03 ноября 2019

account $ отправляет неопределенное значение до уничтожения компонента, это происходит в селекторе маршрутов во время маршрутизации до уничтожения компонента.

Попробуйте

age$ = this.account$.pipe(
  tap(val => {
    console.log('Account obs val is', val);
  }),
  map(account => account.age)
);

https://stackblitz.com/edit/ngxs-repro-ceetsi?file=src/app/components/settings.component.ts

Вы можете видеть, что учетная запись $ испускает неопределенное значение до того, как компонент будет уничтожен.

Это происходит только при переходе от настроек к дому, это ваш селектор маршрута, вызывающий его выделение неопределенным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...