Thursday, November 18, 2021

RxJS - Subjects



Subject is an Observable, and also it is an Observer.



Ex:

 
// Create a Subject
  const subject = new Subject();

// It is an Observable
// => subject can be subscribed to with an Observer
  subject.subscribe(
    val => console.log(val),
    err => console.log(err),
    () => console.log('complete'),
  );

  // It is an Observer
// => it can emit values through next(val), error(vale), and complete()
  subject.next(1);
  subject.next(2);
  subject.complete();


Result:


1
2
complete



Unlike plain Observable, Subjects are multicast.



Ex:

 
// Create a Subject
  const subject = new Subject();

  // Subscribe it by Subscriber A
  subject.subscribe(
    val => console.log('A => ', val),
    err => console.log(err),
    () => console.log('A => complete'),
  );

// Subscribe it by Subscriber B
  subject.subscribe(
    val => console.log('B => ', val),
    err => console.log(err),
    () => console.log('B => complete'),
  );

// Emit an random value
  subject.next(Math.floor(Math.random() * 100));
  subject.complete();

  // Create a plain Observable
  const plainObservalbe$ = new Observable(observer => {
    // Emit an random value
    observer.next(Math.floor(Math.random() * 100));
    observer.complete();
  });

// Subscribe it by Subscriber C
  plainObservalbe$.subscribe(
  val => console.log('C => ', val),
    err => console.log(err),
    () => console.log('C => complete'),
  );

// Subscribe it by Subscriber D
  plainObservalbe$.subscribe(
    val => console.log('D => ', val),
    err => console.log(err),
    () => console.log('D => complete'),
  );


Result:


A => 17
B => 17
A => complete
  B => complete
C => 75
C => complete
D => 56
D => complete



According to the result above, subscribing subject will get the same value because it is multicast.
On the other hand, two plain Observable subscribers have their own independent setup and execution. So they got the different value.


Why we should use asObservable() function of a subject



Since Subjects are both Observables and Observers, not only they can be subscribed to, but also they can emit values through .next(). In order to prevent being misused publicly (such everyone can emit the new value through .next()), we can use asObservable() to wrap it. Then people only can subscribe to it and have no ability to emit new values anymore. Refer to this stackoverflow.


Ex:

 
// Create a Subject and keep it as a private scope
  const subject = new Subject();

  // Creates a new Observable with this Subject as the source.
// And it can be shared as public scope
  const subject$ = subject.asObservable();
  subject$.subscribe(
    val => console.log(val),
    err => console.log(err),
    () => console.log('complete'),
  );

// It is an observer
// => it can emit values through next(val), error(vale), and complete()
  subject.next(1);
  subject.next(2);
  subject.complete();


Result:


1
2
complete


No comments:

Post a Comment