0

I have the following code:

//Subscription 3: role ID to role Name
        af.database.object('/roles/'+businessRole.$value)
        .subscribe((roleData) => {
        //Subscription 4: Get user info
        af.database.object('/users/'+businessRole.$key).subscribe(user => {

Which contains a subscription inside a subscription.

The problem here is that the app waiting for the first one before running the second one. I want to execute both of them in one time, and get the result of each. How I can do that?

I've been using Promise.All() before but:

  1. I would love to know how I can do that with rxjs
  2. I couldn't find a way to get the result of each observable using Promise.All()

Thanks

martin
  • 93,354
  • 25
  • 191
  • 226
TheUnreal
  • 23,434
  • 46
  • 157
  • 277

2 Answers2

5

I believe Observable.forkJoin is exactly what you need to be using in your situation.

This is how your code would look like using forkJoin:

Observable.forkJoin(
this.http.get('/roles/'+businessRole.$value).map((response: Response) => res.json()),
this.http.get('/users/'+businessRole.$key).map((response: Response) => res.json())
).subscribe(data => {
  data[0] // this will contain roleData
  data[1] // this will contain user
},
error => console.log(error));

This is a useful link where you can learn more about observables and how to use forkJoin.

Kerim Emurla
  • 1,141
  • 8
  • 15
2

This creates two Observables that complete after 1000ms and 900ms. When you run this demo you'll see that the first one completes just a moment after the first one to prove that these we're executed in parallel.

let obs1 = Observable.of('HTTP Response 1').delay(1000);
let obs2 = Observable.of('HTTP Response 2').delay(900);

console.log('Start');

obs1.merge(obs2)
    .subscribe(val => console.log(val), undefined, () => console.log('Completed'));

See live demo: http://plnkr.co/edit/hzmpclxDkIhnfTYcWXd5?p=preview

This prints to console:

Start
HTTP Response 2
HTTP Response 1
Completed

If you need forkJoin(), then see my previous answer Observable.forkJoin() doesn't executes :).

Community
  • 1
  • 1
martin
  • 93,354
  • 25
  • 191
  • 226
  • How do I get the output of each observable data? `val` is an array with each observable output? – TheUnreal Oct 29 '16 at 07:34
  • @TheUnreal `merge()` operator emits values from all Observables it get as argument so the callback in `.subscribe()` will be called for every response. – martin Oct 29 '16 at 07:35
  • It's a problem since I need to get and use the output of each, and with this `merge` method I can't determine which observable retruned each output, am I wrong? For example, I'll need to store in `user` variable the first observables data, and `role` variable for the second one. – TheUnreal Oct 29 '16 at 07:37
  • @TheUnreal Then why don't you just simply call `af.database.object('/users').subscribe(...); af.database.object('/roles...').subscribe(...);` separately? They're both called asynchronously and won't block the execution thread. – martin Oct 29 '16 at 07:49
  • Well I can do that but wasn't sure it's the right wa to do it. Anyway, I didn't do that because I'm using those 2 observables to create an object. I put the second observarble result object inside the first one, and create one object contains both. I have just tried to create the object using this, and it actually works. Thanks. – TheUnreal Oct 29 '16 at 08:01