es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo usar rxjs para crear un observable de objeto a partir de otro observable?

Me gustaría exponer un observable en mi servicio, que emite un valor cada vez que se le asigna un valor a un BehaviorSubject (y después de filtrarlo de una lista). Ejemplo de implementación:

export class MyService {

   // Dada una lista de todos los objetos
   private readonly allObjects$: Observable<someobject[]>;
   // Un id de una instancia SomeObject
   private readonly mySubject = new BehaviorSubject<string|undefined>(undefined);

   // Exponer una única instancia de la lista de todos los objetos.
   public readonly myObject$: Observable<someobject|undefined>;

   constructor() {

    this.myObject$ =

        // Pipe en el id del objeto (es decir, 123)
        this.mySubject.pipe(

        // Agregar la lista de todos los objetos
        withLatestFrom(this.allObjects$),

        // Filtrar el objeto cuyo id es 123 de la lista de objetos. Este objeto filtrado 
        // debe ser el valor emitido por myObject$.
        switchMap(
            (info: [string, SomeObject[]]) =>
                info[1].filter(t => t.name === info[0])));
   }
}

Uso:

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

Sin embargo, el fragmento de código anterior produce este error (para el operador withLatestFrom):

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

¿Qué estoy haciendo mal? ¿Cómo lo arreglo?</someobject|undefined></string|undefined></someobject[]>

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El error es causado por la falta de coincidencia de tipos de tupla entre el operador withLatestFrom y la función switchMap. Para solucionar esto, actualiza el tipo del parámetro “info” en switchMap para que coincida con el tipo de tupla producido por withLatestFrom. Aquí está la implementación corregida:

    export class MyService {
       private readonly allObjects$: Observable<someobject[]>;
       private readonly mySubject = new BehaviorSubject<string|undefined>(undefined);
       public readonly myObject$: Observable<someobject|undefined>;
    
       constructor() {
         this.myObject$ = this.mySubject.pipe(
            // Cambia el tipo de tupla para que coincida con el tipo producido por withLatestFrom
            withLatestFrom(this.allObjects$) as OperatorFunction<[string | undefined, SomeObject[]], [string, SomeObject[]]>,
            switchMap(
                ([id, allObjects]) => allObjects.filter(obj => obj.id === id)[0]
            )
         );
       }
    }
    

    Esto debería resolver el error y permitir que el observable emita el objeto filtrado cada vez que se asigna un nuevo valor al BehaviorSubject.</someobject|undefined></string|undefined></someobject[]>

Comments are closed.