Home > Software design >  Why properties value does not change in template onPush strategy?
Why properties value does not change in template onPush strategy?

Time:08-30

Component.ts

@Component({
  selector: 'app-sample',
  templateUrl: './sample.component.html',
  styleUrls: ['./sample.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SampleComponent extends SortableComponent implements OnInit {
  public countNumbers: number = 0;
  public sampleItems;

  constructor(private sampleService: SampleService,) {
    super();
  }

  ngOnInit() {
    this.refreshList();
  }

  private refreshList() {
    this.numberOfAssetsLeftToLoad = this.numberOfAssetsLeftToLoad   1;

this.sampleService
      .getSample()
      .then(
        (response: any) => {
          this.numberOfAssetsLeftToLoad = this.numberOfAssetsLeftToLoad - 1;
          this.sampleItems = response;
        },
        (reason: Error) => {
          this.numberOfAssetsLeftToLoad = this.numberOfAssetsLeftToLoad - 1;
          console.log(reason);
        },
      );
  }
}

Template

<div  *ngIf="numberOfAssetsLeftToLoad !== 0">
      <loader loadingText="Loading Sample..." cssClass="w-50"></loader>
    </div>
    <div  *ngIf="numberOfAssetsLeftToLoad === 0">
      <div *ngFor="let item of sampleItems;">{{item}}</div>
    </div>

The problem is that using OnPush strategy values in the template does not change appropriately as in the ts file. For example, numberOfAssetsLeftToLoad stay 1 and loading does not end.

CodePudding user response:

You must manually tell Angular to perform a change detection. Simply inject ChangeDetectorRef and call markForCheck() where you change a property:

@Component({
  selector: 'app-sample',
  templateUrl: './sample.component.html',
  styleUrls: ['./sample.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SampleComponent extends SortableComponent implements OnInit {
  public countNumbers: number = 0;
  public sampleItems;

  constructor(private cd: ChangeDetectorRef, private sampleService: SampleService,) {
    super();
  }

  ngOnInit() {
    this.refreshList();
  }

  private refreshList() {
    this.numberOfAssetsLeftToLoad = this.numberOfAssetsLeftToLoad   1;
    this.cd.markForCheck();

this.sampleService
      .getSample()
      .then(
        (response: any) => {
          this.numberOfAssetsLeftToLoad = this.numberOfAssetsLeftToLoad - 1;
          this.sampleItems = response;
          this.cd.markForCheck();
        },
        (reason: Error) => {
          this.numberOfAssetsLeftToLoad = this.numberOfAssetsLeftToLoad - 1;
          this.cd.markForCheck();
          console.log(reason);
        },
      );
  }
}
  • Related