westor
westor

Reputation: 1534

How to handle observable object with severeal observable properties?

I have an observable of an object. Additional properties, defined themselve as observable, have be added to the object, when I subscribe.

const obj = {
  a: 'some text'
};
const b$ = of('BBB').pipe(delay(1000));
const c$ = of('CCC');

const obj$ = of(obj).pipe(delay(100));

const res$ = obj$.pipe(
  map(obj => Object.assign({
    b: b$,
    c: c$
  }, obj))
)

const subscribe = res$.subscribe(val => console.log(val));

The output still contains the observables:

{a: "some text", b: Observable, c: Observable}

But the expected output should be:

{a: "some text", b: "BBB", c: "CCC"}

How can I solve this? Here is the StackBlitz: https://stackblitz.com/edit/typescript-6euwct

Upvotes: 1

Views: 111

Answers (2)

Amaresh C.
Amaresh C.

Reputation: 599

If you want to wait until all observables are completed, then you might wanna try forkJoin.

const obj = {
  a: 'some text'
};
const b$ = of('BBB').pipe(delay(1000));
const c$ = of('CCC');

const obj$ = of(obj).pipe(delay(100));

const res$ = forkJoin(
  obj$,
  b$,
  c$
).pipe(map(([obj, b, c]: any) => ({ obj, b, c })))

const subscribe = res$.subscribe(val => console.log(val));

This will wait until every one of those observables is completed, before triggering the subscribe block.

Upvotes: 1

Zlatko
Zlatko

Reputation: 19588

combineLatest will get you there.

combineLatest(b$, c$, obj$)
  .pipe(
    map(([b, c, obj]: any) => ({
      b,
      c, 
      obj
    })),
  )
  .subscribe(console.log);

Any time any of them emits a value, your end subscription fires, e.g. doing this:

const c$ = interval(1000).pipe(map( () => of('CCC')));

Would re-fire the thing every second. Or just interval(1000) would change the value of C every second.

Upvotes: 3

Related Questions