Home > Mobile >  Is there a way to trigger change detection in Angular to update an array in the view when an element
Is there a way to trigger change detection in Angular to update an array in the view when an element

Time:10-25

I have this component with a client property.

import { Component } from '@angular/core';

@Component({
  selector: 'app-update-view',
  templateUrl: './update-view.component.html',
  styles: [
  ]
})
export class UpdateView {

  public client: string[] = ['client 1', 'client 2', 'client 3', 'client 4'];

  constructor() { }
   
  deleteClient() {
    this.client.pop();
  }

}

In the html I print the object like this.

<div class="col md:col-6">
    <div>  
        <strong>Client</strong>
        <pre>{{ Client }}</pre>
    </div>
    <button (click)="deleteClient()">Delete Client</button>
</div>

I know this is not the way to print the array, I should use 'ngFor and print the items one by one but I want to know if there is a way to update the array in the html after deleting a client because right know when I click on Delete Client, the array in the html stays the same.

I ask this question out of curiosity, I know this way of printing arrays is not correct but I want to know if there is any way to update the view.

CodePudding user response:

The direct answer to your question is to inject the ChangeDetectionRef and call markForCheck.

export class UpdateView {

  public client: string[] = ['client 1', 'client 2', 'client 3', 'client 4'];

  constructor(private cdr: ChangeDetectionRef) { }

  deleteClient() {
    this.client.pop();
    this.cdr.markForCheck();
  }

}

But the real answer is to figure out why this doesn't update? The kind of coding that you are doing is called "mutable" coding. This is how people would code in AngularJS. Mutating objects and then running change detection on those objects is why AngularJS had such a slow change detection cycle. The way that Angular's change detection works is that it only runs change detection on an object if the reference to the object (in this case, an array) is a reference to a different object. Since you are calling pop, you're pointing to the same array, so Angular is not likely to run CD on it.

The following code would get you what you want AND trigger Angular's CD. The following code updates this.client to be a new array, which will automatically get the UI to update.

// THIS IS THE RIGHT ANSWER!!!
this.client = this.client.slice(0, -1);

By doing this, you are leaning in on immutable programming, which makes change detection much faster and cheaper.

CodePudding user response:

Try using json pipe, and change <pre>{{ client | json }}</pre> instead of <pre>{{ Client }}</pre>.

<div class="col md:col-6">
  <div>
    <strong>Client</strong>
    <pre>{{ client  | json }}</pre>
  </div>
  <button (click)="deleteClient()">Delete Client</button>
</div>
  • Related