Search code examples
angularangular-signals

Is takeUntilDestroyed unnecessary on a subscription to an observable created via toObservable?


import { Component, input } from '@angular/core';
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';

@Component({ ... })
class MyComponent {
  value = input<string>();

  constructor() {
    toObservable(this.value)
      .pipe(takeUntilDestroyed()) // is this superfluous?
      .subscribe(console.log);
  }
}

The documentation states that toObservable must be called in an injection context, so I am not sure whether it is automatically cleaning up subscriptions or not.


Solution

  • toObservable implementation will use a DestroyRef to invoke complete on the observable it creates. So in a sense yes it is not necessary to have a takeUntilDestroyed() on it if toObservable is invoked in a component.

    However, if toObservable is invoked in a service providedIn root, DestroyRef will never fire onDestroy and your observable will (almost) never be destroyed.

    @Injectable({providedIn: 'root'})
    class MyService() {
    
     myValue = signal(5)
    
     getObservable() {
       return toObservable(this.myValue);
     }
    }
    

    This example is a great illustration of an observable that wouldn't complete automatically.