Home > OS >  How to use rxjs to create an object observable from another observable?
How to use rxjs to create an object observable from another observable?

Time:01-02

I would like to expose an observable in my service, which emits a value each time a BehaviorSubject is assigned a value (and after filtering it from a list). Example implementation:

export class MyService {

   // Given a list of all object
   private readonly allObjects$: Observable<SomeObject[]>;  
   // An id of a SomeObject instance
   private readonly mySubject = new BehaviorSubject<string|undefined>(undefined);

   // Expose a single instance from the list of all objects.
   public readonly myObject$: Observable<SomeObject|undefined>;   

   constructor() {

     
     this.myObject$ = 

        // Pipe in the object id (i.e.: 123)
        this.mySubject.pipe(

        // Add the list of all objects
        withLatestFrom(this.allObjects$),

        // Filter out the object whose id is 123 from the list of objects. This filtered 
        // object should be the value emitted by myObject$.
        switchMap(
            (info: [string, SomeObject[]]) =>
                info[1].filter(t => t.name === info[0])));
   }
}

Usage:

  mySubject.next('123')  
  this.myObject$.subscribe(console.log)  // prints: SomeObject(with id 123)

However the above snippet produces this error (for the withLatestFrom operator):

Argument of type 'OperatorFunction<string | undefined, [string | undefined, 
SomeObject[]]>' is not assignable to parameter of type 'OperatorFunction<string | 
undefined, [string, SomeObject[]]>'.

What am I doing wrong? How do I fix this?

CodePudding user response:

You have defined BehaviorSubject to hold either string or undefined value. So the info array defined within switchMap can have the 0th element as either string or undefined, and hence the type definition needs to specified accordingly. It should be:

    info: [string | undefined, SomeObject[]]

CodePudding user response:

You don't need a higher order observable to subscribe to another observable for this use case, instead of using switchMap(), why don't you use map() or filter() ?

  • Related