У меня есть наблюдаемая служба данных (UserService), которая возвращает текущего пользователя, вошедшего в систему. Я следовал этому руководству - https://coryrylan.com/blog/angular-observable-data-services, в котором описывается использование BehaviorSubject для немедленного возврата текущего пользователя по умолчанию, а затем выдачи реального currentUser после его загрузки или изменения. Сервис в основном такой ...
private _currentUser: BehaviorSubject<User> = new BehaviorSubject(new User());
public currentUser: Observable<User> = this._currentUser.asObservable();
constructor(private http: Http) {}
loadUser() { // app.component onInit and login component call this
return this.http.get('someapi.com/getcurrentuser')
.map(response => <User>this.extractData(response))
.do(
(user) => {
this.dataStore.currentUser = user;
this._currentUser.next(Object.assign(new User(), this.dataStore).currentUser);
},
(error) => this.handleError(error)
)
.catch(error -> this.handleError(error));
}
У меня возникают проблемы, когда пользователь нажимает F5, чтобы перезагрузить весь спа. Когда компонент-потребитель подписывается на currentUser в UserService, он немедленно получает пользователя по умолчанию, в то время как UserService ожидает вызова api для получения фактического пользователя. В момент завершения вызова api UserService отправляет реального пользователя, и все подписчики получают настоящего пользователя. Однако первое значение, генерируемое BehaviorSubject, является значением по умолчанию и всегда имеет идентификатор «undefined», поэтому мы пока не можем сделать следующий вызов api. Фактически, когда приходит реальный пользователь, и я МОГУ сделать действительный вызов, используя user.id, цепная подписка никогда не происходит, и я не получаю значения из ответа.
Я знаю, что делаю что-то глупое, но еще не понял, что именно. Я только что наткнулся на concatMap, но не знаю, как его использовать. Пока я занимаюсь этим, я хотел бы знать, почему приведенный ниже код не работает. Я особенно хочу знать, почему подписка никогда не срабатывает, даже после того, как реальный пользователь входит, просто чтобы помочь моему новичку в понимании Observables.
this.userService.currentUser
.flatMap((user) => {
this.user = user;
// Need to NOT call this if the user does not have an id!!!
this.someOtherService.getSomethingElse(user.id); // user.id is always undefined the first time
})
.subscribe((somethingElse) => {
// This never gets called, even after the real user is emitted by the UserService
// and I see the getSomethingElse() call above get executed with a valid user.id
this.somethingElse = somethingElse;
});