user172902
user172902

Reputation: 3581

Angular 2 Observable alternative syntax

import { UserService } from './Users/edwardhung/Desktop/timesheet-web-app/timesheet-web-app-new/src/app/services/user.service'; I am using angular 2 with firebase. Currently I have the following function that takes a UID to go to one of the branch in firebase to look for a data that stores the path of where the user infomation is stored. When the data is back, I created a second request to go and fetch that data based on the path.

from UserService.ts

getUserInformation(uid: string) {
    return this.angularFire.database.object('/pathForUid/' + uid).map(results => {
        return this.angularFire.database.object('/' + results.path)
    });
}

And this is how I call the function

this.userService.getUserInformation(data.uid)
    .subscribe(result => {
    result.subscribe(res => {
        let user: User = res;
        this.userService.setCurrentUser(user);
    })
});

Everything works fine here except I am finding this syntax abit weird with the two return and two subscribe. When I was coding in Swift, it was just call backs inside call backs without needing to return twice or subscribe twice.

Is this the only and proper way to do this or is there an alternative syntax such that I dont have to subscribe twice? To me it doesn't really make sense to have two subscribe where I call the function. I am thinking maybe there is a way to do something like the following

this.userService.getUserInfoInOneGoWithId(data.uid)
    .subscribe(result => {
    let user: User = result;
});

Upvotes: 0

Views: 440

Answers (1)

maxime1992
maxime1992

Reputation: 23793

As @AngularFrance said, you want to chain your observables.

But instead of using mergeMap, you may want to use switchMap :

// mock the service which returns http response (observable)
// return a user for some uid
const someService =
  (uid) =>
    Observable
      .of({ user: 'Unicorn' })
      // simulate an HTTP delay
      .delay(1500)

const { Observable } = Rx

const obs = Observable.of({  uid: 'some-uid' })

obs
  .do(_ => console.debug('starting an http request'))
  .switchMap(uid =>
    someService(uid)
      .do(_ => console.log('response received !'))
      .map(user => console.debug(user))
  )
  .subscribe()

The result is :

// output instantly :
starting an http request

// outputs 1.5s later :
response received !
{user: "Unicorn"}

Here's a working Plunkr :
https://plnkr.co/edit/s7YUROGAJ9RzHxj5vi82?p=preview (open your console)

Upvotes: 0

Related Questions