0

Maybe my question may seem a possible duplicate of this question. However I do not understand the answer given there so I am asking it again if someone can help me. I have a mat-table which I use it to display customer records. I show following details. Customer Id,First Name, Last Name, City and Status(Active/Inactive). In last column of my mat-table I have a delete button to delete the customer Record. If I delete the record the status changes to Inactive. However in my case the status does not change until I refresh my page. How can I change the status without refreshing my page. I have used new new MatTableDataSource<>([]) to initialize the mat-table again.I thought that would solve my issue but it did not.

HTML Code for mat-table

  // Delete function
  deleteCustomer(element) {
    this.customer360Service.deleteCustomer(element.id).subscribe(
      data => {
        console.log(data);
        console.log(this.customerId);
        this.snackbar.open('Customer Deleted Successfully', 'Close', {
          duration: 3000
        });
        this.customerSearchRecordList = new MatTableDataSource<Customer>([this.customerSearchRecord]);

      },
      err => {
        console.log('***', this.customerId);
        this.snackbar.open('Failed To Delete Customer', 'Close', {
          duration: 3000
        });
      }
    );
  }
<mat-table [dataSource]="customerSearchRecordList" matSort>
      <ng-container matColumnDef="index">
        <mat-header-cell *matHeaderCellDef> Number </mat-header-cell>
        <mat-cell *matCellDef="let element; let i = index">{{ i + 1 }}</mat-cell>
      </ng-container>

      <!-- Customer Id Column -->
      <ng-container matColumnDef="id">
        <mat-header-cell *matHeaderCellDef>Customer Id</mat-header-cell>
        <mat-cell *matCellDef="let element">{{ element.id }}</mat-cell>
      </ng-container>

      <!-- First Name Column -->
      <ng-container matColumnDef="firstName">
        <mat-header-cell *matHeaderCellDef>First Name</mat-header-cell>
        <mat-cell *matCellDef="let element">{{ element.individualCustomer.primaryFirstName }}</mat-cell>
      </ng-container>

      <!-- Last Name Column -->
      <ng-container matColumnDef="lastName">
        <mat-header-cell *matHeaderCellDef>Last Name</mat-header-cell>
        <mat-cell *matCellDef="let element">{{ element.individualCustomer.primaryLastName }}</mat-cell>
      </ng-container>

      <!-- Status Column -->
      <ng-container matColumnDef="status">
        <mat-header-cell *matHeaderCellDef>Status</mat-header-cell>
        <mat-cell
          *matCellDef="let element"
          [ngClass]="{
            positive: element.status == 'Active',
            negative: element.status == 'In Active'
          }"
          >{{ element.status }}</mat-cell
        >
      </ng-container>
      <!-- View Button -->
      <ng-container matColumnDef="actions">
        <mat-header-cell *matHeaderCellDef> Actions </mat-header-cell>
        <mat-cell *matCellDef="let element; let index = index">
          <smd-fab-speed-dial [open]="open" [direction]="direction" [animationMode]="animationMode" [fixed]="fixed">
            <smd-fab-trigger [spin]="true">
              <button color="black" matTooltip="More job actions ..." class="view-data" mat-fab (click)="moreActionToggle()">
                <i class="material-icons">more_horiz</i>
              </button>
            </smd-fab-trigger>
            <smd-fab-actions>
              <button mat-mini-fab color="#b71c1c" matTooltip="View" (click)="transferIndCustData(element)">
                <i class="material-icons large" style="font-size: 28px">
                  pageview
                </i>
              </button>
              <button mat-mini-fab color="#b71c1c" matTooltip="Delete" (click)="deleteCustomer(element)">
                <i class="material-icons large" style="font-size: 28px">
                  delete
                </i>
              </button>
            </smd-fab-actions>
          </smd-fab-speed-dial>
        </mat-cell>
      </ng-container>

      <mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
      <mat-row *matRowDef="let row; columns: displayedColumns; let i = index"></mat-row>
    </mat-table>

I am doing a soft delete which means that my record is not actually removed but the status column shows Inactive instead of Active. Initially if I have 10 customer rows and all are active and now if I delete the first row customer then I will still have 10 rows the only thing that will change is that the first row status column will be changed to In Active.

Cpt.Kitkat
  • 120
  • 4
  • 17
  • https://stackoverflow.com/questions/47581267/how-to-add-data-dynamically-to-mat-table-datasource/56948608#56948608 ? – Eliseo Jul 09 '19 at 16:30

3 Answers3

0

Try:

idColumn = "custId" // to declare your id property name (eg: custId: 1).

deleteCustomer(element) {
this.customer360Service.deleteCustomer(element.id).subscribe(
  data => {
    this.snackbar.open('Customer Deleted Successfully', 'Close', {
      duration: 3000 });
          this.deleteRowDataTable(
            custProd.custProdId,
            this.idColumn, 
            this.paginator1,
            this.dataSource1
          )
   },
  err => {
    this.snackbar.open('Failed To Delete Customer', 'Close', {
      duration: 3000
    });
   }
 );
}

private deleteRowDataTable(recordId, idColumn, paginator, dataSource) {
   this.dsData = dataSource.data
   const itemIndex = this.dsData.findIndex(obj => obj[idColumn] === recordId)
   dataSource.data.splice(itemIndex, 1)
   dataSource.paginator = paginator
}
Prashant Pimpale
  • 10,349
  • 9
  • 44
  • 84
komali
  • 1
  • 3
0

One way to refresh data without reloading the whole HTML page is reassigning the data source in one of Angular's lifecycle hooks. In the below code snippet, to display upto date data I'm using the AfterViewChecked hook. component.ts

ngAfterViewChecked(): void {
  this.lstorage = JSON.parse(localStorage.getItem('employee')!);
  setTimeout(() => {
     this.dataSource = new MatTableDataSource(this.lstorage);
  }, 0);
  
}
Shekhar
  • 1
  • 2
-1

The simple answer you are looking for is replacing your dataSource value of customerSearchRecordList with a

BehaviorSubject<customerSearchRecordList>

or

Subject<customerSearchRecordList>

Anytime there is a change in your source(db), you update the dataSource by passing in the new value as a param to the next method of the Subject/BehaviorSubject

BehaviorSubject or Subject should help fix the issue any time across Angular apps when dealing with dynamic data.

In this particular case. define

dataSource$: Subject<customerSearchRecordList>;

After any CRUD operation using update as an example:

update(somevalue) {
    this.http.post('somelink').subscribe(res => {
       if (all good) {
           // make the http get to get the new source for 
           // customerSearchRecordList and pass the new datasource to your subject.
           this.dataSource$.next(newSearchResult); // **important**
       }
    })
}

in the html

<mat-table [dataSource]="dataSource$" matSort>
.....
</mat-table>
deamon
  • 89,107
  • 111
  • 320
  • 448
saidutt
  • 289
  • 1
  • 7