Search code examples
angularangular-materialangular-material-table

matTable: UI not updating after altering a datasource row


I'm trying to update my dataTable when an user has been edited.

At the moment, the dataSource is updated, but changes are not visible on front part. I mean, my console.log(this.dataSource) show good datas. But on the web page it's not the case.

Here's how I get my dataSource (ngOnInit) :

this.users.users().subscribe(data => {
    this.dataSource.data = data;
});

Here's my update function :

/**
* Update an user
* @param user The user to update
*/
  update(user: User) {
    // users = user's services
    this.users.edit(user)
    .subscribe(
      userEdited => {
        const userIndex = this.dataSource.data.findIndex(usr => usr.id === user.id);

        console.log('Before change :', this.dataSource.data[userIndex], userIndex);

        this.dataSource.data[userIndex] = userEdited;

        console.log('After change :', this.dataSource.data[userIndex], this.dataSource.data);
      }
    );
  }

SOLUTION

I need to call renderRows() function.

So I added a reference on my table like : <table mat-table #table [dataSource]="dataSource">

Then I declare a @ViewChild property like @ViewChild('table', { static: true }) table: MatTable<any>;

Then :

 const userIndex = this.dataSource.data.findIndex(usr => usr.id === user.id);
 console.log('Before change :', this.dataSource.data[userIndex], userIndex);
 this.dataSource.data[userIndex] = userEdited;

 this.table.renderRows(); // <--- Add this line

 console.log('After change :', this.dataSource.data[userIndex], this.dataSource.data);

Solution

  • you might need to call the renderRows() function, see https://material.angular.io/components/table/api

    If the table's data source is a DataSource or Observable, this will be invoked automatically each time the provided Observable stream emits a new data array. Otherwise if your data is an array, this function will need to be called to render any changes.

    /**
    * Update an user
    * @param user The user to update
    */
    update(user: User) {
      this.users.edit(user)
      .subscribe(
        userEdited => {
          const userIndex = this.dataSource.data.findIndex(usr => usr.id === user.id);
          this.dataSource.data[userIndex] = userEdited;
          this.table.renderRows(); // <--- Add this line
        }
      );
    }