Попробуйте использовать switchMap
вместо map
. map
просто преобразует одно значение в другое, тогда как switchMap
позволяет переключаться на другое наблюдаемое.
Не зная слишком много о том, что происходит, я думаю, вы хотите что-то вроде этого:
let user: User;
let account: Account;
return this.as.getAccount(route.params['id']).pipe(
tap((acc: Account) => account = account),
switchMap((acc: Account) => this.as.getUserDetails(acc.access_token)),
// this filter will stop the next steps from running if the user is null
// it will also mean a value isn't emitted
// if you want to emit a null, you will need to modify the pipe
filter((u: User) => u !== null),
tap((u: User) => user = u),
switchMap((u: User) => this.rs.getResults(this.auth.token))
map((res: Result[]) => {
const ud: UserDetails = {
user,
results: res.filter(x => x.userId === account.uid)
};
return ud;
})
);
Обратите внимание, что это больше не отступ, как у вас, а последовательность операторов канала. Всякий раз, когда вы хотите переключиться на новую наблюдаемую, используйте switchMap
или concatMap
. Мы используем map
только для сопоставления результата последней наблюдаемой со значением, которое мы хотим вернуть из функции.
Всякий раз, когда необходимо сохранить состояние из середины канала, я использую нажмите, чтобы назначить ее переменной.
Кроме того, вы делаете (возможно) избыточные вызовы this.rs.getResults(this.auth.token)
. Вызов не изменяется в зависимости от того, что является параметром id
, так что вы можете просто извлечь один раз и прочитать из кэша при последующих вызовах.
Edit: concatMap
также вариант. Они немного разные. И того, и другого достаточно для ответа на этот вопрос - я не собираюсь делать предположения относительно вашего варианта использования.