A Subject is a double nature. It has both the behavior from an Observer and an Observable. Thus the following is possible:
Emitting values
subject.next( 1 )
subject.next( 2 )
Subscribing to values
const subscription = subject.subscribe( (value) => console.log(value) )
To sum it up the following operations exist on it:
next([value])
error([error message])
complete()
subscribe()
unsubscribe()
A Subject
can act as a proxy, i.e receive values from another stream that the subscriber of the Subject
can listen to.
import { interval, Subject } from 'rxjs';
import { take } from 'rxjs/operators';
let source$ = interval(500).pipe(
take(3)
);
const proxySubject = new Subject();
let subscriber = source$.subscribe( proxySubject );
proxySubject.subscribe( (value) => console.log('proxy subscriber', value ) );
proxySubject.next( 3 );
So essentially proxySubject listens
to source$
But it can also add its own contribution
proxySubject.next( 3 ) // emits 3 and then 0 1 2 ( async )
GOTCHA
Any next()
that happens before a subscription is created is lost. There are other Subject types that can cater to this below.
So what's interesting about this? It can listen to some source when that data arrives as well as it has the ability to emit its own data and all arrives to the same subscriber. Ability to communicate between components in a bus like manner is the most obvious use case I can think of. Component 1 can place its value through next()
and Component 2 can subscribe and conversely Component 2 can emit values in turn that Component 1 can subscribe to.
sharedService.getDispatcher = () => {
return subject;
}
sharedService.dispatch = (value) => {
subject.next(value)
}