0

I'm learning Angular's change detection and can't find an answer why the following snippet doesn't work.

Suppose we have a Component with ChangeDetectionStrategy.OnPush set:

@Component({
  selector: 'material-app',
  templateUrl: 'app.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
  public isBusy: boolean;

  public message: any;

  public version = VERSION;

  constructor(
    private readonly httpClient: HttpClient,
    private readonly dialog: MatDialog) {
  }

  public onSeeBugClick(): void {
    this.sendApiRequest();

    this.dialog.open(DialogComponent, {
      width: '250px'
    });
  }

  private sendApiRequest(): void {
    this.message = 'Sending request';
    this.isBusy = true;

    this.httpClient.get<void>('https://jsonplaceholder.typicode.com').pipe(
          finalize(() => {
            this.isBusy = false;
          }))
      .subscribe(
        (): void => {
          console.log('Success from jsonplaceholder.typicode.com');
          this.message = 'Success';
        },
        (error: string): void => {
          console.log('Error from jsonplaceholder.typicode.com');
          this.message = 'Error '+ error.toString() + ': ' + JSON.stringify(error);
        });
  }
}

Here is StackBlitz.

When API request ends up with an error, neither ENABLE ME BACK button disabled state gets updated, nor message text below it do. But if I comment ChangeDetectionStrategy.OnPush line - it works fine.

Could anyone explain why ChangeDetectionStrategy.OnPush strategy doesn't work in this case?

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
  • https://stackblitz.com/edit/angular-material-button-doesnt-enable-xvkhve?file=app/app.component.ts Read https://stackoverflow.com/questions/42312075/change-detection-issue-why-is-this-changing-when-its-the-same-object-referen Http callback doesn't fall into the case when angular checks component with OnPush strategy – yurzui Nov 25 '17 at 05:09
  • @yurzui: Thanks for the explanation! This is strange. I have the same thing (`ChangeDetectionStrategy.OnPush` and `HttpClient` callback which updates `Component`'s public property) in my project and it does work. That's why I was sure that success callback works in this situation. I'll try to find a difference and ping you back. – Alexander Abakumov Nov 25 '17 at 05:31
  • @yurzui: Ok, I've found the reason why it's worked before - there were only calls to a mock API which didn't do actual AJAX request. Is that `this.cdRef.markForCheck();` a preferred way of dealing with API calls in a `ChangeDetectionStrategy.OnPush` component? Are there other options by any chance? – Alexander Abakumov Dec 13 '17 at 20:16

0 Answers0