Home > Back-end >  RxJS: Is there a cleaner (intended) way to conditionally skip the pipeline with a default value?
RxJS: Is there a cleaner (intended) way to conditionally skip the pipeline with a default value?

Time:07-18

Basically, when the products array is empty, I want it to emit an empty array (such that the Angular view updates), but when it does contain products, I want to apply some operations on it. Currently my code is this:

products$: Observable<Product[]> = this.products.asObservable().pipe(
  switchMap((products: Product[]) =>
    products.length === 0
      ? of(products) // or of([])
      : from(products).pipe(
          // Executing some operators resulting in a Product[]
        )
  )
);

To me this code seems a bit cumbersome. Is there a cleaner (perhaps intended) way of doing this in RxJS? Any help is appreciated.

Edit: The same goes for empty objects:

this.orders$.pipe(
  switchMap((someObject) =>
    Object.keys(someObject).length === 0
      ? of([])
      : of(someObject).pipe(
          // Executing some operators resulting in an array
        )
  )
);

When the object is empty, I want to return an empty array, else I want to do some operations on the object.

CodePudding user response:

It's not clear what is the type of this.products.

Assuming is a generic Subject, it seems that this.products will emit a whole array of Product elements (i.e. a value with type Product[]) on each emission, so in your case some other code should be doing some .next(arrayOfProducts) instruction somewhere.

That said, maybe you are trying to return the outcome of the operations you are trying to apply on each of the emitted array products? If so, maybe this code would help:

products$: Observable<Product[]> = this.products.asObservable().pipe(
  switchMap((products: Product[]) =>
    products.length === 0
      ? of(products) // or of([])
      : of(products.map(product => {
        // execute some operation on product to get a (new?) product to return
      }))
  )
);

Please note that you should use switchMap when the value returned from the switch operation is an Observable too (not a simpler array); if the manipulations you want to do don't generate an Observable, maybe you could just .pipe a map operator instead of switchMap.

CodePudding user response:

If I understand the problem right, you do not need to use switchMap but you should be ok with a simple map operator.

The code could look like this

products$: Observable<Product[]> = this.products.asObservable().pipe(
  map((products: Product[]) =>
    products.length === 0
      // if products is an empty array, just return it
      ? products
      // if products is an array of Products, as it is implied in the 
      // of the products variable, then you may have to do some operations
      // on each Product in the array, which can be done for instance with 
      // the map method of Array (not to be confused with the map operator used
      // with Obserables.
      : products.map(product => // do the necessary transformations
  )
)
  • Related