29

I'm trying to avoid nested observables by using forkjoin. The current (nested) version looks like this:

  this.http.get('https://testdb1.firebaseio.com/.json').map(res => res.json()).subscribe(data_changes => {
    this.http.get('https://testdb2.firebaseio.com/.json').map(res => res.json()).subscribe(data_all => {
      /* Do this once resolved */
      this.platform.ready().then(() => {
        this.storage.set('data_changes', data_changes);
        this.storage.set('data_all', data_all);
        document.getElementById("chart").innerHTML = "";
        this.createChart();
      });
    });
  },

    err => {
      this.platform.ready().then(() => {
        console.log("server error 2");
        document.getElementById("chart").innerHTML = "";
        this.createChart();
      });
    });
  }

I can rewrite the first part as:

Observable.forkJoin(
  this.http.get('https://testdb1.firebaseio.com/.json').map((res: Response) => res.json()),
  this.http.get('https://testdb2.firebaseio.com/.json').map((res: Response) => res.json())
)

But i'm not sure how I would then add the .subscribe method to access both data_changes and data_all.

Looking at another example, I know it should look something like .subscribe(res => this.combined = {friends:res[0].friends, customer:res[1]});, but i'm not sure how to adapt this to my example.

Martin
  • 1,060
  • 2
  • 16
  • 28

1 Answers1

47

Try to use combineLatest instead of forkJoin :

With combineLatest :

const combined = Observable.combineLatest(
  this.http.get('https://testdb1.firebaseio.com/.json').map((res: Response) => res.json()),
  this.http.get('https://testdb2.firebaseio.com/.json').map((res: Response) => res.json())
)

combined.subscribe(latestValues => {
    const [ data_changes , data_all ] = latestValues;
    console.log( "data_changes" , data_changes);
    console.log( "data_all" , data_all);
});

You can also handle it by forkJoin , but forkJoin will return data when all calls are finished and return result , but in combineLatest When any observable emits a value, emit the latest value from each.

With forkJoin :

const combined = Observable.forkJoin(
  this.http.get('https://testdb1.firebaseio.com/.json').map((res: Response) => res.json()),
  this.http.get('https://testdb2.firebaseio.com/.json').map((res: Response) => res.json())
)

combined.subscribe(latestValues => {
    const [ data_changes , data_all ] = latestValues;
    console.log( "data_changes" , data_changes);
    console.log( "data_all" , data_all);
});

Call both and check the console log , you will get idea.

Vivek Doshi
  • 56,649
  • 12
  • 110
  • 122
  • 2
    This would be a better answer if it included an explanation of why the OP should favour `combineLatest`. – cartant Apr 02 '17 at 08:43
  • Okay , just one minute. – Vivek Doshi Apr 02 '17 at 08:48
  • If you find out this helpfull , please accept the answer also. – Vivek Doshi Apr 02 '17 at 08:54
  • 7
    Your description of the behaviour of `combineLatest` is incorrect. It won't emit anything until each of the observables it's passed has emitted at least once. And the HTTP observables will emit only once, so how will using it differ from using `forkJoin`, if at all? – cartant Apr 02 '17 at 09:07
  • Yes I know, i think I coundn't explain it very well – Vivek Doshi Apr 02 '17 at 09:12
  • @VivekDoshi will combine latest with work different model httpclients ? Like httpclient.get and httpclient.get can this be combined ? – Eldho Dec 20 '17 at 13:21
  • @Eldho, yes it will. – Vivek Doshi Dec 20 '17 at 13:58
  • i tried but its not working, it show like `this.Employee` cannot be set with `customer` – Eldho Dec 20 '17 at 13:59
  • 1
    A side note, `forkJoin` will only trigger when the observables return a new value after your call `forkJoin`, so if one of the observables has already returned a value `forkJoin` will never trigger next. `combineLatest` will trigger even if the observable has already emitted its value. Thought this might help someone if who comes across this page and can't figure out why their subscribe next function is never being it. – Chris Putnam Nov 06 '18 at 19:04