angular - Bir gözlemlenebilirin diğerinde çağrılması doğru mu?
Üç tane servisime sahibim ve her biri basit bir API çağrısı yapıyor ve değeri istemciye geri döndürüyor, her API çağrısı diğerlerinden alınan bazı verilere bağlı.
İlk abone olduğum Observable gibi kullanıcı verilerini alıyorum, sonra ondan aldığım verilerle ilk Observable'dan alınan iki değeri geçirerek parametreleri alan Observable'ı çağırabilirim, ardından üçüncü Observable, ilk Observable'dan aynı verilere ve ikinci Observable'dan bir parametreye ihtiyaç duyar.
Yani benim kodum şöyle görünüyor:
ngOnInit(): void {
this.profiloService
.profilo(this.idNegozio)
.subscribe((profilo: Profilo) => {
this.profilo = profilo;
this.menuService
.menu(profilo.idNegozio, profilo.piva, 'IT')
.subscribe((menu: Menu[]) => {
this.menu = menu;
this.pluService
.plu(profilo.idNegozio, profilo.piva, 'IT')
.subscribe((plus: Plu[]) => {
this.plus = plus;
this.filterPlu(menu.id);
});
});
});
}
Başka bir Observable'dan Observable'a abone olmak iyi bir yaklaşım mıdır? Eğer değilse en iyi uygulama ne olmalıdır?
Cevap #1
Tüm http çağrıları sıralı olduğundan ve 3. çağrıda ilk http yanıtını kullanmak istediğinizden, ConcateMap'i aşağıdaki gibi kullanmalısınız,
ngOnInit(): void {
this.profiloService.profilo(this.idNegozio)
.pipe(
concatMap((profilo: Profilo) => this.menuService.menu(profilo.idNegozio, profilo.piva, 'IT')
.pipe(
// you should be able to access profilo here
concatMap((menu: Menu[]) => this.pluService.plu(profilo.idNegozio, profilo.piva, 'IT')
.map((plus: Plu[]) => {
this.plus = plus;
this.filterPlu(menu.id);
})
)
)
).subscribe()
}
NOT: Parantez hatalarını lütfen görmezden gelin
Cevap #2
Birinin içinde neredeyse hiç subscribe yapmamalısın. Şöyle bir şey yap:
ngOnInit(): void {
this.profiloService
.profilo(this.idNegozio)
.switchMap((profilo) =>
forkJoin([
of(profilo)
this.menuService.menu(profilo.idNegozio, profilo.piva, 'IT'),
this.pluService.plu(profilo.idNegozio, profilo.piva, 'IT')
])
)
.subscribe(([profilo,menu,plus]) => {
this.profilo = profilo
this.plus = plus
this.filterPlu(menu.id)
this.menu = menu
})
}
