89

I'm going through angular-tour-of-heroes app, and I encountered .subscribe method in routing. Can someone explain what's going on here?

Link for the app: https://embed.plnkr.co/?show=preview

Inside hero-detail.component.ts file,

ngOnInit(): void {
  this.route.paramMap
    .switchMap((params: ParamMap) => this.heroService.getHero(+params.get('id')))
    .subscribe(hero => this.hero = hero);
}
Oriol Roma
  • 329
  • 1
  • 5
  • 9
Sree11
  • 937
  • 1
  • 7
  • 14
  • 32
    welcome to the jungle;-) [hint: rxjs Observables] – dee zg Jul 05 '17 at 09:11
  • 2
    Read about rxjs here. https://bumbu.github.io/javascript-observer-publish-subscribe-pattern/ – Yatin Patel Jul 05 '17 at 09:14
  • simply, it executes the observal – tero17 Jan 02 '18 at 00:38
  • subscribe(hero => this.hero = hero) -- if its success. Otherwise error handling part also there. sample one is : (error: any) => {console.log(error);} one more thing you must import : import { Observable, observable } from '../../../node_modules/rxjs'; – Lova Chittumuri Nov 12 '18 at 11:11

4 Answers4

204

.subscribe is not an Angular2 thing.

It's a method that comes from rxjs library which Angular is using internally.

If you can imagine yourself subscribing to a newsletter, every time there is a new newsletter, they will send it to your home (the method inside subscribe gets called).

That's what happens when you subscribing to a source of magazines ( which is called an Observable in rxjs library)

All the AJAX calls in Angular are using rxjs internally and in order to use any of them, you've got to use the method name, e.g get, and then call subscribe on it, because get returns and Observable.

Also, when writing this code <button (click)="doSomething()">, Angular is using Observables internally and subscribes you to that source of event, which in this case is a click event.

Back to our analogy of Observables and newsletter stores, after you've subscribed, as soon as and as long as there is a new magazine, they'll send it to you unless you go and unsubscribe from them for which you have to remember the subscription number or id, which in rxjs case it would be like :

 let subscription = magazineStore.getMagazines().subscribe(
   (newMagazine)=>{

         console.log('newMagazine',newMagazine);

    }); 

And when you don't want to get the magazines anymore:

   subscription.unsubscribe();

Also, the same goes for

 this.route.paramMap

which is returning an Observable and then you're subscribing to it.

My personal view is rxjs was one of the greatest things that were brought to JavaScript world and it's even better in Angular.

There are 150~ rxjs methods ( very similar to lodash methods) and the one that you're using is called switchMap

Milad
  • 27,506
  • 11
  • 76
  • 85
17

In Angular (currently on Angular-6) .subscribe() is a method on the Observable type. The Observable type is a utility that asynchronously or synchronously streams data to a variety of components or services that have subscribed to the observable.

The observable is an implementation/abstraction over the promise chain and will be a part of ES7 as a proposed and very supported feature. In Angular it is used internally due to rxjs being a development dependency.

An observable itself can be thought of as a stream of data coming from a source, in Angular this source is an API-endpoint, a service, a database or another observable. But the power it has is that it's not expecting a single response. It can have one or many values that are returned.

Link to rxjs for observable/subscribe docs here: https://rxjs-dev.firebaseapp.com/api/index/class/Observable#subscribe-

Subscribe takes 3 methods as parameters each are functions:

  • next: For each item being emitted by the observable perform this function
  • error: If somewhere in the stream an error is found, do this method
  • complete: Once all items are complete from the stream, do this method

Within each of these, there is the potentional to pipe (or chain) other utilities called operators onto the results to change the form or perform some layered logic.

In the simple example above:

.subscribe(hero => this.hero = hero); basically says on this observable take the hero being emitted and set it to this.hero.

Adding this answer to give more context to Observables based off the documentation and my understanding.

Callat
  • 2,928
  • 5
  • 30
  • 47
  • 1
    Hello Callat, I ran a console.log of this example inside of the subscribe method on this.hero. What I got was undefined. Outside of the method this.hero returns the hero's list. Can you explain what exactly this.hero is referring to in this example? Does this.hero become HEROES that the observable returns? I can't seem to find any examples on this problem and would really like to know what is going on with this.hero – QuestForMastery Jun 06 '19 at 03:59
  • Sure @QuestForMastery .subscribe is async meaning it's not expected to return data at the point of page render but as some other point either on or after render. In my example going off the heroes tutorial for Angular 6 hero was the name of the property being returned by the event I subscribed to. If you console log it before the subscribe returns anything youll get undefined as no data arrived yet. I'd recommend looking a bit more into promises and ajax for a better idea as to how that works. But think of observables as a way to embed promises in a better way. – Callat Jul 09 '19 at 20:12
  • ".subscribe(hero => this.hero = hero); basically says on this observable take the hero being emitted and set it to this.hero.", but where is the call of 'next' as you said subscribe take 3 methods as parameter. – user1169587 May 28 '20 at 04:37
5

A Subscription is an object that represents a disposable resource, usually the execution of an Observable. A Subscription has one important method, unsubscribe, that takes no argument and just disposes of the resource held by the subscription.

import { interval } from 'rxjs';

const observable = interval(1000);
const subscription = observable.subscribe(a=> console.log(a));

/** This cancels the ongoing Observable execution which
was started by calling subscribe with an Observer.*/

subscription.unsubscribe();

A Subscription essentially just has an unsubscribe() function to release resources or cancel Observable executions.

import { interval } from 'rxjs';

const observable1 = interval(400);
const observable2 = interval(300);

const subscription = observable1.subscribe(x => console.log('first: ' + x));
const childSubscription = observable2.subscribe(x => console.log('second: ' + x));

subscription.add(childSubscription);

setTimeout(() => {
// It unsubscribes BOTH subscription and childSubscription
subscription.unsubscribe();
}, 1000);

According to the official documentation, Angular should unsubscribe for you, but apparently, there is a bug.

murthy naika k
  • 559
  • 6
  • 12
  • Re: auto-unsubscribe – Angular only does that in select situations. For instance, HttpClient is designed to auto-unsubscribe once the response has been returned (so you don't have to unsubscribe to i.e. HttpClient.get). @HostListener unsubscribes when component is destroyed. Anything using the async pipe will unsubscribe automatically when it receives the 'complete' event. It all depends on the scenario; read https://netbasal.com/when-to-unsubscribe-in-angular-d61c6b21bad3 – wosevision Jan 16 '20 at 17:35
0

subscribe() -Invokes an execution of an Observable and registers Observer handlers for notifications it will emit. -Observable- representation of any set of values over any amount of time.

JoBaHP
  • 99
  • 1
  • 3
  • 1
    Please use the correct markdown formatting for answers. Code should be inside these code blocks like so ```Heres some code```. This can be done using the (`) symbol three times before the start of your code and the end of your code. – XtremeDevX Jul 17 '20 at 16:58