I’ve been coding in Angular for a little while now. I’ve come across many different types of styles, and I have been able to observe what doesn’t work. Until recently, I think I’ve discovered a way that RxJS Observables work best in Angular.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import {UntilDestroy, untilDestroyed} from "@ngneat/until-destroy";

@UntilDestroy()
@Component({...})
export class ExampleComponent implements OnInit {
  data !: string;

  ngOnInit(): void {
    this.exampleObservable.pipe(untilDestroyed(this)).subscribe(data => {
      this.data = data;
    })
  }
}

I think this is the best way to handle observables, because it leaves all the logic in the TypeScript file, it recognizes the lifespan and memory leak possibility of the observable, and it utilizes Angular lifecycle hooks as they ought to be.

I’m more or less in favor of separation of styles/logic in files. Template code goes over here, styling goes over there, and scripts go here. One alternative to the previous solution would be to use the async template pipe. The async template pipe is very handy, but sometimes it may not be needed. The previous solution is much more versatile than the handiness of the async template pipe. Instead, RxJS pipes are much more versatile and familiar than template pipes. Those can easily show more logic that might be written. And that logic can stay with the script file.

I like the explicitness of the untilDestroyed(this). This will unsubscribe the observable when the component lifecycle ends so that there are no memory leaks. Of course, the async template pipe can unsubsribe when the template renders, but what if the observable gets another emission from state management? The async template pipe can’t help there. With the previous solution, the observable can keep alive for the lifespan of the component.

An Angular component has a lifecycle. The OnInit lifecycle hook is meant for data setup. This is a perfect spot to put an observable! Then that observable can assign values to the class fields when it gets emissions.

There are a few more aspects to this solution, but I’ll just leave this for now. Maybe I’ll write more on those later.