5.0 Creating a self observable
-- 5.1 Creating observables
-- 5.2 Subscribing to observables
-- 5.3 Executing observables
============================================
Angular uses observables extensively in the event system and the HTTP service.
1.0 Definition
Observables are lazy
++ You could think of lazy observables as newsletters. For each subscriber a new newsletter is created. They are then only send to those people, and not to anyone else.
Observables can have multiple values over time
++ Now if you keep that subscription to the newsletter open, you will get a new one every once and a while. The sender decides when you get it but all you have to do is just wait until it comes straight into your inbox.
Observables push.
++ Observables are a new way of pushing data in JavaScript. An observable is a Producer of multiple values, “pushing” them to subscribers.
2.0 Compared with Promise
Type
Return Value
Cancelable
Promises
One
No
Observables
Multi
Yes
3.0 Push vs pull
A key thing to understand when using observables is that observables push.
Push and pull are two different ways that describe how a data producer communicates with the data consumer.
Pull
consumer decides when to get data from data producer
Push
Data producer decides when to give data to data consumer
Every javascript function uses the pull.
Promises are the most common way of push in JavaScript today.
4.0 In Angular
Here is the example of setting up HTTP requests.
import { Observable } from "rxjs/Rx"
import { Injectable } from "@angular/core"
import { Http, Response } from "@angular/http"
@Injectable()
export class HttpClient {
constructor(
public http: Http
) {}
public fetchUsers() { <=== here is a simple fetchUsers method of HttpClient returns an observable
return this.http.get("/api/users").map((res: Response) => res.json())
}
}
The purpose is to display the users in some sort of list.
! Since this method returns an observable we have to subscribe to it. In Angular we can subscribe to an observable in two ways:
4.1 Subscribe Manner 1
Using async pipe in template
Benefit: Angular deals with subscription during the lifecycle of a component
Angular will automatically subscribe and unsubscribe
import the “CommonModule” into module for the async pipe
import { Component } from "@angular/core"
import { Observable } from "rxjs/Rx"
// client
import { HttpClient } from "../services/client"
// interface
import { IUser } from "../services/interfaces"
@Component({
selector: "user-list",
templateUrl: "./template.html",
})
export class UserList {
public users$: Observable<IUser[]>
constructor(
public client: HttpClient,
) {}
// do a call to fetch the users on init of component
// the fetchUsers method returns an observable
// which we assign to the users$ property of our class
public ngOnInit() {
this.users$ = this.client.fetchUsers()
}
}
<!-- We use the async pipe to automatically subscribe/unsubscribe to our observable -->
<ul class="user__list" *ngIf="(users$ | async).length">
<li class="user" *ngFor="let user of users$ | async">
{{ user.name }} - {{ user.birth_date }}
</li>
</ul>
+Using the dollar sign in the name of a variable that is an observable, is considered best practice. This way it’s easy to identify if your variable is an observable or not.
4.2 Subscribe Manner 2
with subscribe() method
upside: could do something with the data before displaying it
downside: must manage subscription self.
import { Component } from "@angular/core"
// client
import { HttpClient } from "../services/client"
// interface
import { IUser } from "../services/interfaces"
@Component({
selector: "user-list",
templateUrl: "./template.html",
})
export class UserList {
public users: IUser[]
constructor(
public client: HttpClient,
) {}
// do a call to fetch the users on init of component
// we manually subscribe to this method and take the users
// in our callback
public ngOnInit() {
this.client.fetchUsers().subscribe((users: IUser[]) => {
// do stuff with our data here.
// ....
// asign data to our class property in the end
// so it will be available to our template
this.users = users
})
}
}
<ul class="user__list" *ngIf="users.length">
<li class="user" *ngFor="let user of users">
{{ user.name }} - {{ user.birth_date }}
</li>
</ul>
Method 2 Keeping your subscriptions open while not using them is a memory leak and therefore not good.
5.0 Creating a self observable
through new Observable( ) call
subscribed to by an observer;
calling next( )
calling unsubscribe( )
import { Observable } from "rxjs/Observable"
// create observable
const simpleObservable = new Observable((observer) => {
// observable execution
observer.next("bla bla bla")
observer.complete()
})
// subscribe to the observable
simpleObservable.subscribe()
// dispose the observable
simpleObservable.unsubscribe()
5.1 Creating observables
Creating observables is easy, just call the new Observable() and pass along one argument which represents the observer. Therefore it's usually called “observer” as well.
5.2 Subscribing to observables
Remember, observables are lazy. If you don’t subscribe nothing is going to happen. It’s good to know that when you subscribe to an observer, each call of subscribe() will trigger it’s own independent execution for that given observer. Subscribe calls are not shared among multiple subscribers to the same observable.
5.3 Executing observables
The code inside an observables represents the execution of the observables. On the parameter that was given when creating the observable there are three functions available to send data to the subscribers of the observable:
“next”: sends any value such as Numbers, Arrays or objects to it’s subscribers.
“error”: sends a Javascript error or exception
“complete”: does not send any value.
Calls of the next are the most common as they actually deliver the data to it’s subscribers. During observable execution there can be an infinite calls to the observer.next(), however when observer.error() or observer.complete() is called, the execution stops and no more data will be delivered to the subscribers.
Example
observable.service.ts
import {Observable} from 'rxjs/Observable';
export class ObservableService{
newService(): Observable<Date>{
return new Observable ( <=======
observer => {
setInterval(()=>observer.next(new Date()),1000);
}
);
}
}
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import {ObservableService} from "./obervable.service";
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
providers: [ObservableService], <========
bootstrap: [ AppComponent ]
})
export class AppModule { }
Guidelines
============================================
Angular uses observables extensively in the event system and the HTTP service.
1.0 Definition
Observables are
lazy
++ You could think of lazy observables as newsletters. For each subscriber a new newsletter is created. They are then only send to those people, and not to anyone else.Observables can have
multiple values
over time ++ Now if you keep that subscription to the newsletter open, you will get a new one every once and a while. The sender decides when you get it but all you have to do is just wait until it comes straight into your inbox.Observables
push
. ++ Observables are a new way of pushing data in JavaScript. An observable is a Producer of multiple values, “pushing” them to subscribers.2.0 Compared with Promise
3.0 Push vs pull
A key thing to understand when using observables is that observables push.
Push and pull are two different ways that describe how a data producer communicates with the data consumer.
get
data fromdata producer
give
data todata consumer
Every javascript function uses the pull. Promises are the most common way of push in JavaScript today.
4.0 In Angular
Here is the example of setting up HTTP requests.
The purpose is to display the users in some sort of list.
4.1 Subscribe Manner 1
async pipe
in template4.2 Subscribe Manner 2
subscribe()
methodMethod 2 Keeping your subscriptions open while not using them is a memory leak and therefore not good.
5.0 Creating a self observable
new Observable( )
callsubscribed
to by anobserver
;next( )
unsubscribe( )
5.1 Creating observables
Creating observables is easy, just call the
new Observable()
and pass alongone argument
whichrepresents the observer
. Therefore it's usually called “observer” as well.5.2 Subscribing to observables
Remember, observables are
lazy
. If you don’t subscribe nothing is going to happen. It’s good to know that when you subscribe to an observer, each call ofsubscribe()
will trigger it’s own independent execution for that given observer.Subscribe calls are not shared among multiple subscribers to the same observable.
5.3 Executing observables
The code inside an observables represents the execution of the observables
. On the parameter that was given when creating the observable there are three functions available to send data to the subscribers of the observable:“next”
: sends any value such as Numbers, Arrays or objects to it’s subscribers.“error”
: sends a Javascript error or exception“complete”
: does not send any value.Calls of the
next are the most common as they actually deliver the data to it’s subscribers
. During observable execution there can be an infinite calls to theobserver.next()
, however whenobserver.error()
orobserver.complete()
is called, the execution stops and no more data will be delivered to the subscribers.Example
observable.service.ts
app.module.ts
app.component.ts
References
[1] https://medium.com/@luukgruijs/understanding-creating-and-subscribing-to-observables-in-angular-426dbf0b04a3