Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to subscribe to an observable, constructor or ngoninit in Angular [closed]

I know this is posted all over SO and the internet but I'm reading so many different things, I'm just a little confused now.

2 QUESTIONS -

  1. Where is the best place to subscribe to my component, the constructor(), or in NgOnInit()?
  2. Should I use a pipe when subscribing to an Observable so that Angular can destroy it or so I don't have to use ngondestroy? A little confused as to why there are pipes after subscribing?

Here is an example of one of my services where, in my navbar component, I subscribe to listening to a window size change coming from a service.

In my constructor, I have this -

this.responsiveService.getMobileStatus()
  .subscribe(mobileStatus => {
    this.isMobile = mobileStatus.status;
    if (mobileStatus.width < 568) {
      this.inputPlaceholder = this.placeholderWithSearch;
    } else {
      this.inputPlaceholder = this.placeholderWithoutSearch;
    }
  });
like image 739
user1186050 Avatar asked Dec 03 '25 05:12

user1186050


2 Answers

  1. it's good practice to use ngOnInit to subscribe because @Input bindings are not initialized till this lifecycle hook, so they're not ready in the constructor, and often observables can depend upon these values. Even if they don't, it's just a good practice thing to keep it consistent, and always in the same place.

  2. you should use the async pipe whenever practical to avoid manual subscription management, but this is not always possible or reasonable.

like image 130
bryan60 Avatar answered Dec 07 '25 04:12

bryan60


I would say better to use an async pipe and let angular handle the unsubscribing. It produces cleaner code;

lets consider the code where the subscribing is in the constructor

export class MyClassComponent implements OnInit, OnDestroy {
  sub: any;
  componentName: any;
  constructor(private navbarService: NavbarService) {
  }
  ngOnInit() {
    this.sub = this.navbarService.getComponentNameObv()
    .subscribe(componentName => {
      this.componentName = componentName;
    });
  }
  ngOnDestroy() {
    this.sub.unsubscribe()
  }
}

With an async pipe we can refactor

export class MyClassComponent {
  componentName$ = this.navbarService.getComponentNameObv();
  mobileStatus$ = this.responsiveService.getMobileStatus().pipe(
    tap(mobileStatus => {
      this.isMobile = mobileStatus.status;
      if (mobileStatus.width < 568) {
        this.inputPlaceholder = this.placeholderWithSearch;
      } else {
        this.inputPlaceholder = this.placeholderWithoutSearch;
      }
    })
  )
  constructor(private navbarService: NavbarService) {
  }
}

The code is much shorter and also easier to test

like image 26
Owen Kelvin Avatar answered Dec 07 '25 04:12

Owen Kelvin