Reputation: 101
Actually I want to call another function with an array value as a parameter. I am getting the array from a subject:
this.shopService.$getShops().pipe(map(
shops => {
console.log(shops[0]);
}
)).subscribe();
The subscription is based on this:
private newShopsSubj = new BehaviorSubject(undefined);
setShops(shops: any) {
this.newShopsSubj.next(shops);
}
$getShops(): Observable<any> {
return this.newShopsSubj.asObservable();
}
Actually the code is working...but the console.log
call ends with undefined
. Somehow I am finding no appropriate solution.
I want to do like :
this.shopService.$getShops().subscribe(resp => {
this.shopService.getProductsByShopID(resp[0].id).subscribe(resp
=> {do something...};});
But it actually fails as resp[0].id
stays undefined
...
My attempts with the map failed.
Any help highly appreciated...
Thanks
Hucho
Upvotes: 1
Views: 3142
Reputation: 73367
Like in other answer... if $getShops()
is called before a value is set, you will get undefined
as that is the initial value. You can initialize it as an empty array, or use rxjs filter
to filter out the undefined
value. Also I would chain these requests with for example switchMap
or mergeMap
, as it's not recommended to nest subscriptions. So I suggest the following:
private newShopsSubj = new BehaviorSubject([]);
public newShopsSubj$ = this.newShopsSubj.asObservable();
and the component code:
import { mergeMap, filter } from 'rxjs/operators';
import { of } from 'rxjs';
// ...
this.shopService.newShopsSubj$.pipe(
mergeMap((shops: any[]) => {
// do a check that that there is an object
if (shops && shops.length) {
return this.shopService.getProductsByShopID(shops[0].id)
}
// no shops, so return...
// empty array, since assuming the above function returns array of products
return of([]);
})
).subscribe((products: any[]) => {
// check if products exist and do your magic!
})
or like mentioned, have your BehaviorSubject initial value as undefined
and filter
away those value(s):
this.shopService.newShopsSubj$.pipe(
filter(shops => !!shops)
mergeMap((shops: any[]) => {
// .....
Please note that I've used any
here. Don't use it. Type your data to models! (I prefer interfaces).
And remember to unsubscribe in OnDestroy
!!
Upvotes: 2
Reputation: 2820
BehaviourSubject
emits the current value to new subscribers.
here you are initializing it with undefined
initial value
private newShopsSubj = new BehaviorSubject(undefined);
So when you subscribe it as below
this.shopService.$getShops().subscribe(resp => {
this.shopService.getProductsByShopID(resp[0].id).subscribe(resp
=> {do something...};});
Initially, it will get resp
as undefined.
to fix this either you can use Subject
instead of BehaviorSubject
or initialize BehaviourSubject
with a proper shop object.
Upvotes: 0