#angular #observable
Вопрос:
У меня есть два наблюдаемых :
constructor(
private afAuth:AngularFireAuth,
private db:AngularFireDatabase
) {
this.afAuth.authState.subscribe(x=>
{
this.userId=x?.uid;
console.log(this.userId);
});
console.log(this.userId);
this.db.list('users/' this.userId '/movies-favourited').valueChanges().subscribe(data=>{
this.favouriteList=data;
});
}
Как мне убедиться, что я получу идентификатор пользователя в первом наблюдаемом, прежде чем получать список во втором наблюдаемом?
Ответ №1:
Правильный способ сделать это-использовать switchMap
, как показано ниже:
this.afAuth.authState.pipe(
switchMap(user => {
if(user) {
this.userId = user.uid;
this.db.list('users/' this.userId '/movies-favourited')
.valueChanges().subscribe(data => {
this.favouriteList = data;
});
}
})
);
Вы можете прочитать больше об этом switchMap
здесь.
Комментарии:
1. Также вы можете использовать оператор объединения rxjs, learnrxjs.io/learn-rxjs/operators/combination/concat
Ответ №2:
Вы можете либо заменить первое наблюдаемое на обещание
или
Вы можете поместить второе наблюдаемое внутри первого, как это:
this.afAuth.authState.subscribe(x=>
{
this.userId=x?.uid;
console.log(this.userId);
this.db.list('users/' this.userId '/movies-favourited').valueChanges().subscribe(data=>{
this.favouriteList=data;
});
});
Ответ №3:
Как только первый наблюдаемый объект успешно получит данные, подписавшись, он подпишется на второй наблюдаемый объект, который решит вашу проблему.
constructor(
private afAuth: AngularFireAuth,
private db: AngularFireDatabase
) {
this.afAuth.authState.subscribe(x => {
this.userId = x?.uid;
console.log(this.userId);
this.db.list('users/' this.userId '/movies-favourited').valueChanges().subscribe(data => {
this.favouriteList = data;
});
console.log(this.userId);
});
}
Комментарии:
1. Можете ли вы объяснить, почему и какие подходы являются лучшими ?
2. Внутренняя подписка остается живой и может неожиданно сработать (каждый раз, когда срабатывает внешняя подписка, вы создаете новую внутреннюю подписку). Этот подход действительно укусит вас в более сложных сценариях. Вы действительно хотите «подключить» наблюдаемые объекты с помощью соответствующих операторов rxjs, таких как switchmap, чтобы в итоге получить только одну подписку. Убийство внешнего тогда также убьет » внутреннего’.
Ответ №4:
Это должно быть решением вашей задачи.
this.afAuth.authState
.subscribe(
(x: any) => {
this.userId = x?.uid;
if (x.uid) {
this.db.list('users/' this.userId '/movies-favourited').valueChanges()
.subscribe(
(data: any) => {
this.favouriteList = data;
},
(error) => {
console.log(error);
});
}
},
(error) => {
console.log(error);
}
);
Дополнительные предложения по оптимизации кода:
- Подумайте о том, чтобы поместить свой код в жизненный цикл ngOnInit() вместо конструктора.
- Определите типы данных ваших переменных » x » и «данные».
- Не забудьте отписаться.
- Как-то справляйтесь со своими ошибками.