I am learning Angular2 by this official cookbook.
The below code just appears out of sudden. Why "missionAnnounced$" doesn't have a variable declaration? let missionAnnounced$ = ... What is the logic of the below code?
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MissionService {
// Observable string sources
private missionAnnouncedSource = new Subject<string>();
private missionConfirmedSource = new Subject<string>();
// Observable string streams
missionAnnounced$ = this.missionAnnouncedSource.asObservable();
missionConfirmed$ = this.missionConfirmedSource.asObservable();
// Service message commands
announceMission(mission: string) {
this.missionAnnouncedSource.next(mission);
}
confirmMission(astronaut: string) {
this.missionConfirmedSource.next(astronaut);
}
}
But rxjs offers different types of Subjects, namely: BehaviorSubject, ReplaySubject and AsyncSubject.
RxJS (Reactive Extensions for JavaScript) is a library for reactive programming using observables that makes it easier to compose asynchronous or callback-based code.
In comparison to a regular Observable, a Subject allows values to be multicasted to many Observers. A Subject and its subscribers have a one-to-many relationship. A Subject can be an Observable as well as an Observer. They hold a registry of many listeners to multiple Observables.
Requiring a dependencies to be install via npm doesn't mean that it will end up in your bundles when you run the application, but Angular does need RxJs. Which operators are compiled into your bundles depends upon which you use or are used by Angular.
An Observable
only allows for subscribing, while a Subject
allows for both publishing and subscribing (a subject is an observable). So using a Subject
allows your service to be used as both a publisher and a subscriber.
@Component({})
class ComponentOne {
constructor(private service: MissionService) {}
onClick() {
service.announceMission('mission started');
}
}
@Component({})
class ComponentTwo {
constructor(private service: MissionService) {
service.missionAnnounced$.subscribe(mission => console.log(mission))
}
}
@Component({})
class ComponentThree {
constructor(private service: MissionService) {
service.missionAnnounced$.subscribe(mission => console.log(mission))
}
}
Now every one that wants to subscribe to the mission announced event can just subscribe. The ComponentOne
will be the one emitting the mission announced event.
Why "missionAnnounced$" doesn't have a variable declaration?
It does. missionAnnounced$
is the variable name, being assigned the Subject
in its observable form. Class member variables don't use let
What is the logic of the below code?
Subscribers subscribe to the observables (the $
variables), while publishers call the announceMission
and confirmMission
. All subscribers to missionAnnounced$
and missionConfirmed$
, respectively, will receive those events.
To complement the previous answer, you will find ample details in the following SO link : What are the semantics of different RxJS subjects?
In short, an Rxjs subject implements both the Observable
, and the Observer
interface (see the link for more details about the different flavours and behaviours of subject). The standard subject used here acts as a pipe, and pass through its Observable
interface all the values it receives on its Observer
interface. The asObservable
function call that you see in the code hides the implementation of the Observer
interface, so you cannot inadvertently use it when you are not supposed too, i.e. you can then only use this subject as you use any regular observable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With