Bitly
Bitly

Reputation: 948

Data not refreshing in table Angular 8

I have implemented a table in Angular 8 using angular material and AWS Lambda as a backend. I have a multi select dropdown, when I select values and click on generate button the table row is created with the time stamp and the selected values (all in one column separated by ,). I am able to generate the table row and the display the data but:

  1. Random values are displayed instead of the selected values.
  2. If I navigate away from the component screen and come back then correct values get displayed.

How can I implement it correctly so the correct values are displayed as soon as new row is added?

HTML:

<mat-select [formControl]="dataCtrl" [multiple]="true" required (selectionChange)="selectionChange($event)">
                <mat-option>
              <ngx-mat-select-search placeholderLabel="Search Data" noEntriesFoundLabel="No Matching Data Found" [formControl]="dataFilterCtrl"></ngx-mat-select-search>
            </mat-option>
              <mat-option *ngFor="let val of filteredData | async" [value]="val.value">
                {{val.name}}
              </mat-option>
            </mat-select>
          </mat-form-field>
    <button mat-raised-button (click)="generate()" class="download-button">Generate</button> //button to create data row


<div class="datatable-container" *ngIf="details">

    <table mat-table class="table-editable" [dataSource]="details" matSort (matSortChange)="sortData($event)" class="mat-elevation-z8">
        <ng-container matColumnDef="createddate">
            <th mat-header-cell *matHeaderCellDef> Date created </th>
            <td mat-cell *matCellDef="let element">{{element.created_date | date :'mediumDate'}} </td>
        </ng-container>

        <ng-container matColumnDef="data">
            <th mat-header-cell *matHeaderCellDef> Data </th>
            <td mat-cell *matCellDef="let element">
                <ng-container *ngFor="let rule of element.data" >
                  <span> {{rule}}</span> 
                </ng-container>
            </td>
        </ng-container>
        
     <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
     <tr mat-row *matRowDef="let row; columns: displayedColumns; let tableid=index"></tr>
    </table>
</div>

TS File:

 public filteredData: ReplaySubject<any[]> = new ReplaySubject<any[]>(1);
 ngOnInit() {
    this.filteredData.next(this.data.slice());
    this.filteredData.valueChanges
      .pipe(takeUntil(this._onDestroy))
      .subscribe(() => {
        this.filterAllData();
      });
}
private filterAllData() {
  if (!this.data) {
    return;
  }
  let search = this.cohortMultiFilterCtrl.value;
  if (!search) {
    this.dataFilterCtrl.next(this.data.slice());
    return;
  } else {
    search = search.toLowerCase();
  }
  // filter the banks
  this.filteredData.next(
    this.data.filter(bank => bank.name.toLowerCase().indexOf(search) > -1)
  );
}

generate(){
    let msg = '';

   // aws lambda logic here

   
    lambda.invoke(params, (err, data) =>{
      if (err) {
       //show error
      }
      else {
        this.url = data.Payload;
        this.url = JSON.parse(this.url);
        msg = this.url.msg;
        if(msg === "workorder available"){
          this.commonService.showSnackBar('Data already exists');
        }
        else{
          this.dbScan();
          this.commonService.showSnackBar("Data generated");
        }
      }
    })
  }

 dbScan(){
  
    // aws lambda related info

    var params: any;
    var document = new AWS.DynamoDB.Document();

    if(this.sharedService.sharedUser.role === "User"){
      params = { TableName: environment.table};
    }
    
// some dynamo db logic
    docClient.scan(params,(err,response) => {

      if(err){
        console.log(err);
      } else {
        this.details.data = response.Items;

        for (let i = 0; i <= this.details.data.length; i++){
            this.dataSplit[i] = this.details.data[i].data.split(',');
            this.splitted.push(this.dataSplit[i]);
            this.userDetails.data[i]['data'] = this.splitted[i];
        }
        this.isEditable.length=this.details.data.length
        for(let i =0; i<this.isEditable.length;i++){
          this.isEditable[i]= false;
        }
        this.details.sortingDataAccessor  = (item, property) => {
          switch (property) {
            case 'ID': return item.name ? item.name.toLowerCase() : '';
            default: return item[property];
          }
        };
        const sortedData = this.details.data.sort((a, b) => parseInt(b['id'])-parseInt(a['id']));
        this.details.data = sortedData;
        //this.userDetails.sort = this.sort;
      }
    });
  }

Upvotes: 0

Views: 728

Answers (1)

Narayanan Ramanathan
Narayanan Ramanathan

Reputation: 1400

#1. Set the data directly to datasource

this.details = response.Items;

#2 Looks like your are iterating the data array to display the data column in table. So make sure that your table data format proper. Eg.

let tabledata = [
{ id: '', created_date: '', data: ['valone','valtwo']},
{ id: '', created_date: '', data: ['valone','valtwo']}
]

May be in your case before setting the data to table datasource split the values if it is a string with comma separated vales,

this.details = response.Items.map(d=>{
d.data = d.data.split(',')
return d;
});

Possible reasons that the below code did not work,

this.details.data = response.Items;

for (let i = 0; i <= this.details.data.length; i++){
    this.dataSplit[i] = this.details.data[i].data.split(',');
    this.splitted.push(this.dataSplit[i]);
    this.userDetails.data[i]['data'] = this.splitted[i];
}
  • datasourcce was assigned before the data column was split
  • the split data is not assigned back to the same row, instead it was assigned to other variables (this.dataSplit[i] and this.userDetails.data[i])

Upvotes: 2

Related Questions