Subject

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 )
1
2

Subscribing to values

const subscription = subject.subscribe( (value) => console.log(value) )
1

To sum it up the following operations exist on it:

next([value])
error([error message])
complete()
subscribe()
unsubscribe()
1
2
3
4
5

Acting as a proxy

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 );
1
2
3
4
5
6
7
8
9
10
11
12

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 )
1

GOTCHA

Any next() that happens before a subscription is created is lost. There are other Subject types that can cater to this below.

Business case

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)
}
1
2
3
4
5
6
7