Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJS combineLatest on object of Observables?

Tags:

rxjs5

I've found myself with a mixed object of values and observables. Something like:

const mixedObject = {
  field1: "Hello",
  field2: Rx.Observable.of('World'),
  field3: Rx.Observable.interval(1000),
};

What would be the best way of doing something like a combineLatest on this object to get a stream of plain objects.

For example, I'd like to do something like:

Rx.Observable.combineLatest(mixedObject).subscribe(plainObject => {
  console.log(plainObject.field1, plainObject.field2, plainObject.field3);
  // Outputs: 
  // > Hello World 0
  // > Hello World 1
  // > Hello World 2
});
like image 233
nicholas Avatar asked Nov 14 '16 04:11

nicholas


1 Answers

You didn't specify if field1 is always a value while field2 and field3 are observables. I will try to give a more general solution.

function mixedToSync(obj: any): Observable<any> {
  return Observable.combineLatest(
    Object.keys(obj).map((key: string) => {
      let value = obj[key];
      if(Observable.prototype.isPrototypeOf(value)){
        return value.map(v => ({[key]: v}));
      } else {
        return Observable.of({[key]: value});
      }
    }))
      .map(propsObservables => Object.assign({}, propsObservables));
}

and then you can use it on your object:

 mixedToSync(mixedObject).subscribe(v => console.log(v));

Or to match your example:

mixedToSync(mixedObject).subscribe(v => console.log(v.field1, v.field2, v.field3));
like image 127
Meir Avatar answered Jan 01 '23 00:01

Meir