toni rmc
toni rmc

Reputation: 878

Angular, observable subscribing to promise

I'm learning Angular from angular.io and I think I have pretty good grasp on Observables and Promises (yes I know they are not Angular specific).

However in the examples I have found something that confuses me.

So not to copy/paste everything; we have HeroService service class

One of the methods is this:

getHero(id: number | string) {
     return heroesPromise
     .then(heroes => heroes.find(hero => hero.id === +id));
}

No issues there, method uses heroesPromise calls then which returns Promise<Hero>.
So bottom line getHero() returns Promise.

Second component uses this HeroService in variable named service.
This is the code in other component which confuses me:

ngOnInit() {
    this.route.params
    // (+) converts string 'id' to a number
   .switchMap((params: Params) => this.service.getHero(+params['id']))
   .subscribe((hero: Hero) => this.hero = hero);
}

So what I'm confused is this part within switchMap() callback:

this.service.getHero(+params['id'])

This obviously returns Promise<Hero> because that is what getHero() returns.

But then inner Observable's (created by switchMap) subscribe() method looks like this:

subscribe((hero: Hero) => this.hero = hero)

As you can see callback of subscribe() takes Hero, not Promise<Hero> which is what callback of switchMap() returns.

Why is that, any thoughts?

Upvotes: 0

Views: 4090

Answers (1)

Sasxa
Sasxa

Reputation: 41254

You have to remember that Promise and Observable are "just" wrappers for callbacks. When you chain then()s in Promise chain or use operators with Observable chains you are passing function or a value from one callback to the next.

Consider this fake code:

const fn = (something) => { return other(something); }

Observable.from([1, 2, 3])
  .map(o => fn(o))
  .swithMap(o => Promise.resolve(o => fn(o)))
  .swithMap(o => Observable.of(o => fn(o)))

You use switchMap() to get a value from some wrapped callback asynchronously (either from Promise, or Observable). map() is a synchronous operator and you are dealing with values directly.

If you want more details about how things work, watch this awesome talk by André Staltz, and You will learn RxJS.

Upvotes: 1

Related Questions