Search code examples
angularrxjsreactive-programmingreactivexobject-properties

Rxjs - remap object with observables as values


I got an observable like this:

  const original = Observable.of({
    a: this.http.get('https://jsonplaceholder.typicode.com/todos/11'),
    b: this.http.get('https://jsonplaceholder.typicode.com/todos/22'),
    c: this.http.get('https://jsonplaceholder.typicode.com/todos/33')
  });

I need to resolve the inner observables and get something like this in the subscribe handler:

  {
    a: ResponseFromServer,
    b: ResponseFromServer,
    c: ResponseFromServer,
  }

How should I approach this problem?

Thanks.

EDIT: I've figured it out, read below.

It seems that not many people know that *Map operators used to have something called resultSelector as their second argument. Now in rxjs v6, you can do the same with inner map, let me show you.

const original = Observable.of({
    a: this.http.get('https://jsonplaceholder.typicode.com/todos/11'),
    b: this.http.get('https://jsonplaceholder.typicode.com/todos/22'),
    c: this.http.get('https://jsonplaceholder.typicode.com/todos/33')
});

const transformed = original.pipe(
    mergeMap(sourceValue => 
        forkJoin(_.values(sourceValue)).pipe(map(resolvedHttpRequests => {
            // here you have access to sourceValue as well as resolvedHttpRequests so you can do manual join to match the data.
        }))
    )
)

Solution

  • Update for 2020

    forkJoin(
      // as of RxJS 6.5+ we can use a dictionary of sources
      {
        google: ajax.getJSON('https://api.github.com/users/google'),
        microsoft: ajax.getJSON('https://api.github.com/users/microsoft'),
        users: ajax.getJSON('https://api.github.com/users')
      }
    )
      // { google: object, microsoft: object, users: array }
      .subscribe(console.log);
    

    https://www.learnrxjs.io/learn-rxjs/operators/combination/forkjoin