coreui/coreui-angular

Smart Table not updating the data.

32x0lf opened this issue · 6 comments

Hi,

I am trying to display a data using smart table. I am confused why it was not updating it's new data. I tried to add or update the column value but the table did not reflect the new data.

here is my ts code

this.orderService.ImportOrders(this.userId,xml).subscribe({
      next: (res:any)=>{
        //console.log(res)
         data = this.tableData.map((item,index) => {
          if (item['error']!== undefined) {
            item['error'] = res[index].error;
          }
          if (item['errorflag']!== undefined) {
            item['errorflag'] = res[index].errorFlag
          }

          return item;
        });
       
      },
      complete:() =>{
        this.tableData = data
        this.changeDetectorRef.detectChanges();
        console.log('new data',this.tableData)
      }
    })
and here is my smart table template 
     <c-smart-table #smartTable="cSmartTable" activePage  clickableRows [columnSorter]="true"
            [columns]="columns" header 
            [items]="tableData"
            pagination 
    
            [tableProps]="{ hover: true, striped: true, responsive: true }">

            <ng-template cTemplateId="tableData" let-columnName="columnName" let-item="item"
                let-tdContent="tdContent">
                <td [cTableActive]="smartTable.tableDataCellProps(item, columnName)?.['active']"
                    [cTableColor]="smartTable.tableDataCellProps(item, columnName)?.color"
                    [cAlign]="smartTable.tableDataCellProps(item, columnName)?.align"
                    [ngClass]="smartTable.tableDataCellClasses(item, columnName)"
                    [ngStyle]="sortedColumnKey === columnName ? sortedColumnStyle: {}">

                    <ng-container [ngSwitch]="columnName">
                      
                        <ng-container *ngSwitchCase="'StartDate'">
                            {{(item[columnName]) | date : dateFormat}}
                        </ng-container>

                        <ng-container *ngSwitchCase="'ExpirationDate'">
                            {{(item[columnName]) | date : dateFormat}}
                        </ng-container>

                        <ng-container *ngSwitchCase="'error'">
                            <span>{{item.error}}</span>
                          </ng-container>
                        
                        <ng-container *ngSwitchDefault>
                            {{tdContent}}
                        </ng-container>
                    </ng-container>
                </td>
            </ng-template>
        </c-smart-table>
    I am using angular 14 
    
    Thanks in advance

@32x0lf
We do not know much about your orderService. It seems ImportOrders returns an Observable that you can subscribe to, providing partial Observer with next and complete notification callbacks. The complete will be called only once - when the producer is done and will send no more next values.

Questions:

  • When your observable completes? (Does it complete at all?) -> Do you see 'new data' in the console log (when)?
  • What happens if you move the assignment this.tableData = data from complete() to next()?
this.orderService.ImportOrders(this.userId, xml).subscribe({
  next: (res:any) => {
    this.tableData = this.tableData.map((item, index) => {
      // ... 
    });
    console.log('new data', this.tableData)
  }
})

Also:

  • What's the initial value of tableData?
  • If there is no error or errorflag in the res array, there will be no change to the tableData. You'll get the exact copy of tableData array. Is this right?
  • If there is an error or errorflag in the tableData array row (aka item), item.error will be overwritten with res[index].error - it mutates item object. What about returning a shallow copy on item object?
return {...item};

Hi @xidedix ,

Yes, I saw the changes in the console. The initial tableData has error and errorflag. I just overwrite the value when I call the api.

Hi @xidedix ,

I am opening this issue again. Actually I closed this issue before because I decided to use the generic table in bootstrap due to some issue with smart table not updating the value. And now, We want to use the smart table for this because we need some of the features of it but the problem is the smart table did not detect the changes from the array when the array is updated.

The array is TableData and it is perfectly binding when adding items to it and displays it into the smart table. The problem comes when I tried to update the the record of TableData that binds to smart table. Kindly check if I am doing this right.

EditPrice(item:any){
    const price = 200;

    let indextoUpdate = this.TableData.findIndex((x:any)=>x.idx == item.idx);
    alert(indextoUpdate)
    this.TableData[indextoUpdate].price = price;
    this.TableData[indextoUpdate].total = price * this.TableData[indextoUpdate].qty;
    this.TableData = [...this.TableData];

    console.log('edit price',this.TableData)
  }

The console log shows the recent changes or the new updated values but in the Smart Table, the records were still the same it seems it was not detected that there was a changed in the array.

Please advise. Thank you

@32x0lf
What happens when you clone your array like this?:

this.TableData = JSON.parse(JSON.stringify(this.TableData))

Hi @xidedix ,

It works. It changes the display. but why it needs to be parse?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions