Наблюдаемый загружается один раз, пустой после перемещения в сторону и обратно

#angular #rxjs #observable

Вопрос:

У меня есть служба, которая предоставляется в корневом каталоге с наблюдаемой:

 organizationSubject = new Subject<Organization>();
organization$ = this.organizationSubject.asObservable();

...

constructor(private http: HttpClient) {
    this.http
      .get<Organization>('organization')
      .subscribe((organization) => this.organizationSubject.next(organization));
  }

 

В OrganizationSettings компоненте я назначаю глобальное наблюдаемое локальному наблюдаемому в ngOnInit :

 this.organization$ = this.organizationService.organization$.pipe(
      tap((organization) => {
       // side effects here
      })
 

со следующим шаблоном:

 <div class="mt-6" *ngIf="organization$ | async as organization" [formGroup]="form">
  {{ organization.name }}
</div>
 

Когда я перехожу на маршрут, где я был OrganizationSettings в первый раз, страница отображается так, как ожидалось, и я вижу div с Name of my organization .

Теперь, когда я перехожу на другой маршрут и возвращаюсь, я не вижу названия организации.

Я что-то здесь упускаю? Я ничего не понимаю…

Ответ №1:

Вероятно, вам следует использовать a BehaviorSubject или a ReplaySubject(1) вместо базового Subject , так как он не будет выдавать последние результаты.

Комментарии:

1. Спасибо вам за быстрый и правильный ответ. Я заменил Subject на ReplaySubject(1) и теперь получаю ожидаемые результаты.

2. Это было связано с так называемой проблемой «позднего подписчика», если вам интересно узнать об этом больше. Альтернативой могло бы быть использование оператора shareReplay ( learnrxjs.io/learn-rxjs/operators/multicasting/sharereplay ), что может свести ваш сервисный код к простому organization$ = this.http .get<Organization>('organization').pipe(shareReplay(1))

3. Я бы не рекомендовал использовать shareReplay(1) с горячими наблюдаемыми. Это сделает наблюдаемое живым «навсегда», даже если вы перейдете на другую страницу и это может привести к утечке памяти. Использование publishReplay(1), refCount() лучше. Пример: blog.strongbrew.io/share-replay-issue