简体   繁体   中英

Pipe Observable subscription with map angular

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

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 !!

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM