I'm trying to use Ag-Grid for Angular to show datasets that I'm downloading from my back-end.
The component that it is supposed to show the table visualization is the following
dataset.component.html
<div class='body-container'>
<ag-grid-angular
style="width: 1250px; height: 650px;"
class="ag-theme-balham"
[enableFilter]="true"
[pagination]="true"
[rowData]="rowData"
[columnDefs]="columnDefs">
</ag-grid-angular>
</div>
dataset.component.ts
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { DatasetService } from 'src/app/services/datasets.service';
@Component({
selector: 'app-dataset',
templateUrl: './dataset.component.html',
styleUrls: ['./dataset.component.css']
})
export class DatasetComponent implements OnInit {
columnDefs = [];
rowData = [];
datasetId;
constructor(private router: ActivatedRoute,
private datasetService: DatasetService) {
debugger;
this.router.queryParams.subscribe(async params => {
this.datasetId = params['id'];
});
}
async ngOnInit() {
if (this.datasetId !== null || this.datasetId !== undefined) {
await this.datasetService.showDataset(this.datasetId).toPromise().then((res) => {
let dataset = JSON.parse(res['data']);
const jsonKeys = Object.keys(dataset);
jsonKeys.forEach((el) => {
this.columnDefs.push(
{
headerName: el,
field: el
});
});
const maxLength = Object.keys(dataset[jsonKeys[0]]).length;
for (let i = 0; i < maxLength; i++) {
let row = {}
jsonKeys.forEach((el) => {
row[el] = dataset[el][i];
});
this.rowData.push(row);
}
debugger;
});
}
}
}
What I basically do is, since I don't know per-time how my columns and data are going to look like, to instantiate them on init of that component so that they can be passed to the ag-grid component. Sadly, this is not working.
I've also seen that the official guide is stating that, for fetching remote data, I should do
<div class='body-container'>
<ag-grid-angular
style="width: 1250px; height: 650px;"
class="ag-theme-balham"
[enableFilter]="true"
[pagination]="true"
[rowData]="rowData | async"
[columnDefs]="columnDefs">
</ag-grid-angular>
</div>
but adding the async pipeline throws me this error
core.js:6014 ERROR Error: InvalidPipeArgument: '' for pipe 'AsyncPipe'
at invalidPipeArgumentError (common.js:6367)
at AsyncPipe._selectStrategy (common.js:7243)
at AsyncPipe._subscribe (common.js:7224)
at AsyncPipe.transform (common.js:7202)
at Object.eval [as updateDirectives] (DatasetComponent.ngfactory.js:21)
at Object.updateDirectives (core.js:44780)
at checkAndUpdateView (core.js:44271)
at callViewAction (core.js:44637)
at execComponentViewsAction (core.js:44565)
at checkAndUpdateView (core.js:44278)
Could anybody point me in the right direction?
Thankfully, found the answer... Essentially, Angular was rendering everything on random order, without helping me understanding very well what was happening.
All I did was
dataset.component.html
<div class='body-container'>
<ag-grid-angular
style="width: 1250px; height: 650px;"
class="ag-theme-balham"
[enableFilter]="true"
[pagination]="true"
(gridReady)="onGridReady($event)"
>
</ag-grid-angular>
</div>
Removing the binding of the colDefs and rowData. Instead, when the grid is ready...
dataset.component.ts
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { DatasetService } from 'src/app/services/datasets.service';
@Component({
selector: 'app-dataset',
templateUrl: './dataset.component.html',
styleUrls: ['./dataset.component.css']
})
export class DatasetComponent implements OnInit {
columnDefs = [];
rowData = [];
datasetId;
constructor(private router: ActivatedRoute,
private datasetService: DatasetService) {
debugger;
this.router.queryParams.subscribe(async params => {
this.datasetId = params['id'];
});
}
async ngOnInit() {
}
async onGridReady(params) {
await this.datasetService.showDataset(this.datasetId).toPromise().then((res) => {
let dataset = JSON.parse(res['data']);
const jsonKeys = Object.keys(dataset);
jsonKeys.forEach((el) => {
this.columnDefs.push(
{
headerName: el,
field: el
});
});
const maxLength = Object.keys(dataset[jsonKeys[0]]).length;
for (let i = 0; i < maxLength; i++) {
let row = {}
jsonKeys.forEach((el) => {
row[el] = dataset[el][i];
});
this.rowData.push(row);
}
debugger;
});
params.api.setColumnDefs(this.columnDefs);
params.api.setRowData(this.rowData);
}
}
I just fetch the data from the server, force the function to wait for the download and then set the columns and the rowdata