2

I have an HttpClient service which is updating the data at backend. During the processing at backend, I' am displaying a loading state by doing this.isLoading = true, and after the successfully processing, I' am removing that loading state in subscribe() by using this.isLoading = false;.

Now I changed my code to use ChangeDetectionStrategy.OnPush and the loading state is not vanishing anymore. I know the change detection in ChangeDetectionStrategy.OnPush occurs when an input property is changed or when an object reference is changed during an event on component etc.

In my case, do I have to manually call ChangeDetectorRef.detectChanges() to trigger change detection or am I missing something?

Edit

Just to clear, I' am using this.isLoading to show/hide loading state by adding/removing class on an HTML element accordingly. For example,

<div [class.processing]="isLoading"></div>

Imran Latif
  • 985
  • 8
  • 21
  • Does the component recieve @Input() from an other component ?, if not remove `ChangeDetection.OnPush()` o you can use `async` pipe. – JSingh Sep 29 '17 at 18:27
  • @JSingh, thanks for commenting. No the component didn't receive `@Input`, it maintains a local variable `isLoading` (boolean) to show/hide loading state. I think `async` won't work with boolean? I have updated the question, please view again. – Imran Latif Sep 29 '17 at 18:57
  • If the component didn't receive @Input then it won't trigger the changes. Can you post your template – JSingh Sep 29 '17 at 18:58
  • @JSingh, just updated the question. Please see the updated one. Thanks. – Imran Latif Sep 29 '17 at 18:59
  • Try changing `[class.processing]` to `
    `
    – JSingh Sep 29 '17 at 19:01
  • Same effect. They are essentially the same. This has something to do with change detection not getting triggered in `subscribe()`. – Imran Latif Sep 29 '17 at 19:09

1 Answers1

2

When setting ChangeDetectionStrategy to OnPush, change detection will run ONLY when an input has changed. Since you are subscribing to an observable and changing a local variable, angular will not be notified of this change so you have to let it know yourself. The recommended way is to use ChangeDetectorRef.markForCheck() which will perform change detection on the tree branch above your component

enter image description here

There is more is more info on this in this great thoughtram article

And an excellent presentation here by Pascal Precht

masimplo
  • 3,674
  • 2
  • 30
  • 47