7

When is asObservable() needed on a Subject (e.g. BehaviorSubject) to get a observable of the subject? The subject isself can be casted to an Observable as well.

Questions

  1. What are the technical differences between name1$ and name2$?
  2. Which one should be used (name1$ or name2$)?

Code Sample

import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs';

export class Person {
  private nameSubject: BehaviorSubject<string> = new BehaviorSubject<string>('lorem');

  public get name1$(): Observable<string> {
    return this.nameSubject.asObservable();
  }

  public get name2$(): Observable<string> {
    return this.nameSubject;
  }

  public setName(value: string): void {
    this.nameSubject.next(value);
  }
}

Thank You for your answers in advance!

Horace P. Greeley
  • 882
  • 1
  • 10
  • 18
  • When using `asObservable()` you get an error when accessing `next`. When you're casting you can cast the Observable back to a type that let's you call `next`. See: https://stackblitz.com/edit/rxjs-qhxv2u – frido Nov 29 '19 at 13:24

3 Answers3

10

In general, it's recommended to use asObservable() only when using RxJS in JavaScript. With TypeScript you can use just type casting and it won't let you call next() and so on.

private nameSubject: BehaviorSubject<string> = new BehaviorSubject<string>('lorem');
public nameSubject$: Observable<string> = this.nameSubject;

This is the officially recommended way of turning Subjects to Observables in TypeScript.
For details see https://github.com/ReactiveX/rxjs/pull/2408#issuecomment-282077506.

martin
  • 93,354
  • 25
  • 191
  • 226
7

asObservable() creates a new Observable, which wraps the Subject, so the wrapped observable doesn't have next() method, as well as complete() and error(). I think it makes more sense in JavaScript, where returned object isn't restricted by it's type. But in TypeScript you can hide these methods just by narrowing the type, it should be enough in most cases. You just tell that an Observable is returned and a user of the API doesn't know that it's a Subject; of course it can be casted back to Subject, but that is not how an API should be used.

See also: When to use asObservable() in rxjs?

Valeriy Katkov
  • 33,616
  • 20
  • 100
  • 123
3

There is not much difference, with asObservable() it mainly just block your access to observer methods - complete, next , error to prevent you from accidentally calling them

const a = new Subject();
console.log(a.asObservable().next)
// undefined

it is better to return asObservable() to be on the safe side if you not using that particular stream as observer

Fan Cheung
  • 10,745
  • 3
  • 17
  • 39