angulartypescriptangular12ngx-datatable

Angular tusharghoshbd-ngx-datatable - ERROR TypeError: arr.forEach is not a function


In Angular-12, I am implementing tusharghoshbd-ngx-datatable.

I have my API JSON endpoint as:

{
  "message": "Companies successfully Retrieved.",
  "error": false,
  "code": 200,
  "results": {
    "company": {
      "id": 1,
      "name": "NIKITA PLC",
      "website": "www.niikita.com",
      "country": {
        "id": 31,
        "name": "Canada",
      }
    }
  }
}

Component:

@ViewChild('actionTpl', {
  static: true
}) actionTpl!: TemplateRef < any > ;
@ViewChild('addressTpl', {
  static: true
}) addressTpl!: TemplateRef < any > ;
@ViewChild('countryTpl', {
  static: true
}) countryTpl!: TemplateRef < any > ;
@ViewChild('idTpl', {
  static: true
}) idTpl!: TemplateRef < any > ;

panelShow = true;
options = {};
data = [];
allCompanyList: any[] = [];
company!: ICompany;
dataBK = [];
columns: any = {};
columnsWithFeatures: any
isLoading = false;
isSubmitted = false;
data1: any;

constructor(
  private fb: FormBuilder,
  private companyService: CompanyService,
  private router: Router,
  private store: Store < AppState > ,
) {}

ngOnInit(): void {
  this.isLoading = true;
  this.loadMyCompany();
  this.loadDatatable();
}

loadMyCompany() {
  this.companyService.getMyCompany().subscribe(
    data => {
      this.allCompanyList = data.results.company;
      console.log(this.allCompanyList);
    },
    error => {
      this.store.dispatch(loadErrorMessagesSuccess(error));
      this.isLoading = false;
    }
  );
}

loadDatatable() {
  this.columns = [{
      key: 'id',
      title: '<div class="blue"><i class="fa fa-id-card-o"></i> SN.</div>',
      width: 60,
      sorting: true,
      cellTemplate: this.idTpl,
      align: {
        head: 'center',
        body: 'center'
      },
      vAlign: {
        head: 'bottom',
        body: 'middle'
      }
    },
    {
      key: 'name',
      title: '<div class="blue"><i class="fa fa-user"></i> Company</div>',
      width: 100,
      sorting: true,
    },
    {
      key: 'website',
      title: '<div class="blue"><i class="fa fa-envelope"></i> Website</div>',
      align: {
        head: 'left'
      },
      width: 100,
      sorting: true
    },
    {
      key: 'country',
      title: '<div class="blue"><i class="fa fa-calendar"></i> Country</div>',
      align: {
        head: 'left'
      },
      width: 100,
      sorting: true,
      cellTemplate: this.countryTpl
    },
    {
      key: '',
      title: '<div class="blue">Action</div>',
      align: {
        head: 'center',
        body: 'center'
      },
      sorting: false,
      width: 80,
      cellTemplate: this.actionTpl
    }
  ];
}

HTML:

<ngx-datatable tableClass="table table-striped table-bordered table-hover" [data]="allCompanyList" [columns]="columns" [options]="options">
  <ngx-caption>
    <div class="row">
      <div class="col-sm-6 col-xs-6 col-6 ">
        <b>
                                <i class="fa fa-table" aria-hidden="true"></i>
                                {{ pageLabel }}
                            </b>
      </div>

    </div>
  </ngx-caption>

  <ng-template #addressTpl let-row let-rowIndex="rowIndex" let-columnValue="columnValue">

  </ng-template>
  <ng-template #idTpl let-rowIndex="rowIndex" let-row="row">
    {{rowIndex+1}}
  </ng-template>
  <ng-template #countryTpl let-row let-rowIndex="rowIndex" let-columnValue="columnValue">
    {{columnValue.name}}
  </ng-template>
  <ng-template #actionTpl let-row let-rowIndex="rowIndex" let-columnValue="columnValue">
  </ng-template>

</ngx-datatable>

When I loaded the page, I got this error:

core.js:6456 ERROR TypeError: arr.forEach is not a function

at NgxDatatableComponent.set data [as data] (tusharghoshbd-ngx-datatable.js:291)

at Object.ngOnChangesSetInput [as setInput] (core.js:1509)

at setInputsForProperty (core.js:10937)

at elementPropertyInternal (core.js:9984)

at Module.ɵɵproperty (core.js:14764)

at CompanyProfileComponent_Template (company-profile.component.html:29)

at executeTemplate (core.js:9579)

at refreshView (core.js:9445)

at refreshComponent (core.js:10616)

at refreshChildComponents (core.js:9242)

Then this is highlighted (company-profile.component.html:29)

[data]="allCompanyList"

in

<ngx-datatable tableClass="table table-striped table-bordered table-hover" [data]="allCompanyList" [columns]="columns" [options]="options">

When I did console.log(this.allCompanyList) in the component, I got:

{id: 1, name: "NIKITA PLC", website: "www.nikita.com"}

country: {id: 31, name: "Canada"}

country_id: 31

name: "Nikita PLC"

website: "www.nikita.com"

How do I get this resolved?

Thanks.


Solution

  • Issue & Concern

    From your JSON, data.results.company is an object, while ngx-database's [data] expects that it will receive the data with array type.

    {
      "message": "Companies successfully Retrieved.",
      "error": false,
      "code": 200,
      "results": {
        "company": {
          "id": 1,
          "name": "NIKITA PLC",
          "website": "www.niikita.com",
          "country": {
            "id": 31,
            "name": "Canada",
          }
        }
      }
    }
    

    Solution

    Cast data.results.company to array type.

    this.allCompanyList = [data.results.company];
    

    Sample Solution on StackBlitz