Home > OS >  API response data not showing in DOM
API response data not showing in DOM

Time:10-31

here as you can see I am calling a service and response data is bind to ELEMENT_DATA variable. but hard corded value is only showing in UI. API response data not showing. while I am console the ELEMENT_DATA response data is already there. but it's not rendering on UI. what mistake I am doing here.

I am using Angular and Angular material for ui.

import { Component, OnInit } from '@angular/core';
import { EnumsDataService } from '@app/management/services/enums/enums-data.service';

export interface PeriodicElement {
  inventoryId: string;
  inventoryName: string;

}
@Component({
  selector: 'app-test-comp',
  templateUrl: './test-comp.component.html',
  styleUrls: ['./test-comp.component.scss']
})
export class TestCompComponent implements OnInit {

  // data:any=[];
  ELEMENT_DATA: PeriodicElement[] = [
    {inventoryId: "1", inventoryName: 'Hydrogen'},
    {inventoryId: "2", inventoryName: 'Helium',},
  ];
  constructor(private _EnumsDataService: EnumsDataService) { }

  ngOnInit(): void {
   this.getInventoryTypes();
  }
  getInventoryTypes() {
    this._EnumsDataService.getInventoryTypes().then((res:any) => {
       // this.inventoryTypes = _.concat([this.allTypes], res);
    console.log(res)
    res.map((item:any)=>{
      let obj={
        inventoryId:item.invTypeId,
        inventoryName:item.invTypeName
      }
      this.ELEMENT_DATA.push(obj)
    }) 
    });
    console.log("ELEMENT_DATA---------------",this.ELEMENT_DATA)
}

displayedColumns: string[] = ['inventoryId', 'inventoryName'];
dataSource = this.ELEMENT_DATA;
}

angular material code for UI

<table mat-table [dataSource]="dataSource" >
  <ng-container matColumnDef="inventoryId">
    <th mat-header-cell *matHeaderCellDef> invId. </th>
    <td mat-cell *matCellDef="let element"> {{element.inventoryId}} </td>
  </ng-container>


  <ng-container matColumnDef="inventoryName">
    <th mat-header-cell *matHeaderCellDef> invName </th>
    <td mat-cell *matCellDef="let element"> {{element.inventoryName}} </td>
  </ng-container>
  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

imagedescx

CodePudding user response:

The solution to your problem can be found in the angular material documentation (https://material.angular.io/components/table/overview#getting-started):

Since the table optimizes for performance, it will not automatically check for changes to the data array. Instead, when objects are added, removed, or moved on the data array, you can trigger an update to the table's rendered rows by calling its renderRows() method.

You can do this by changing the content of your then function to the following:

this.dataSource = [
  ...this.ELEMENT_DATA, 
  ...res.map((item:any) => ({
        inventoryId:item.invTypeId,
        inventoryName:item.invTypeName
      })
  )
]

This way you create a new array. Angular will notice that the reference has changed and will detect the changes accordingly. Of course you can also call the renderRows function instead to trigger this manually.

Note: I am not sure if you understand how the map function on arrays work. The way you used it forEach would make more sense, since you are not returning elements from the function.

CodePudding user response:

the dataSource needs to be re-assigned after getting the response to trigger change detection and render the new content

export class TestCompComponent implements OnInit {

  ELEMENT_DATA: PeriodicElement[] = [
    { inventoryId: "1", inventoryName: 'Hydrogen' },
    { inventoryId: "2", inventoryName: 'Helium', },
  ];

  displayedColumns: string[] = ['inventoryId', 'inventoryName'];
  dataSource = this.ELEMENT_DATA;

  constructor(private _EnumsDataService: EnumsDataService) { }

  ngOnInit(): void {
    this.getInventoryTypes();
  }

  getInventoryTypes() {
    this._EnumsDataService.getInventoryTypes().then((res: any) => {
      // this.inventoryTypes = _.concat([this.allTypes], res);
      console.log(res)
      res.map((item: any) => {
        let obj = {
          inventoryId: item.invTypeId,
          inventoryName: item.invTypeName
        }
        this.ELEMENT_DATA.push(obj)

      })
        this.dataSource = [...this.ELEMENT_DATA];
    });
    console.log("ELEMENT_DATA---------------", this.ELEMENT_DATA)
  }
}
  • Related