Detect property change inside component in Angular

Viewed 124

I am learning more about Angular and I am trying to run a method after I change a property. This is my code

isLoading = false;

ngOnInit() {
    this.isLoading = true;
    this._myService.getContent().subscribe(
        (response: IContent) => {
            this.isLoading = false;
            this.doSomething();
            // console.log(response);
        },
        err => {
            this.isLoading = false;
            this.doSomething();
            console.log(err);
        }
    );
}

doSomething() {
     console.log('some thing')
}

And with this I want to execute doSomething() after isLoading is set to false (like putting for example .then(() => {this.doSomething()}) after setting). I know i can put doSomething() in timeout like

setTimeout(() => this.doSomething(),10);

and that will work but i think there is a better way. I have searched for solution and found about ChangeDetectorRef which i am not sure on how to implement it on this case. There also might be a different approach with which i am not familiar.

2 Answers

In your case doSomething should be called after the Observable has completed. You can use the finalize pipe for that:

isLoading = false;

ngOnInit() {
  this.isLoading = true;

  this._myService.getContent().pipe(
    finalize(() => {
      this.isLoading = false;
      this.doSomething();
    })
  ).subscribe({
    next: (response: IContent) => console.log(response),
    error: (error: any) => console.log(err)
  });
}

doSomething() {
     console.log('some thing')
}

If you -always- want to run doSomething() on setting this.isLoading to false. You can use a getter/setter:

get isLoading(): boolean {
  return this._isLoading;
}

set isLoading(loading: boolean) {
  this._isLoading = loading;

  if (loading) {
    this.doSomething();
  }
}

private _isLoading: boolean;

Or you can just use an extra method in your class:

setLoading(loading: boolean): void {
  this.loading = loading;

  if (loading) {
    this.doSomething();
  }
}

The last two options are frowned upon though, because the functions are no longer pure as they most likely introduce side effects

Please try to implement onPush or ChangeDetectionStrategy in your component

Doing this will instruct Angular to run change detection on these components and their sub-tree only when new references are passed to them versus when data is simply mutated.

Run this.ref.markForCheck() or this.ref.detectChanges() when you update your variable(or do something) and want it to reflect in html

Please check the following links for more information

https://angular.io/api/core/ChangeDetectionStrategy

https://alligator.io/angular/change-detection-strategy/

Related