Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AgGrid/Angular 2: No access to setRowData(). grid renders, no rowData is displayed

Solved (sort of) I believe my solution is jerry rigged and indicates that I set up my mongoose model improperly.

The answer below did help me solve my problem so I checked it, but in the end the reason for the blank data rows was incorrect identifiers in the property

ie. in my-gridcomponent-name.component.ts

gridOptions.columnDef.field 

I needed set the field property with the actual database field names/identifiers.

I was using the names/identifiers that I assigned in the mongoose Schema and not the database's actual field names/identifiers. For example, the Schema identifiers where all one word lower case while the database identifiers started with an uppercase and may have an _ between words.



Question starts here....


I am fetching an array of JSON objects from MongoDB and want to display them in agGrid.

$ng version angular-cli: 1.0.0-beta.28.3 node: 6.9.2 os: win32 x64 
@angular/common: 2.4.10 
@angular/compiler: 2.4.10 
@angular/core: 2.4.10 
@angular/forms: 2.4.10 
@angular/http: 2.4.10 
@angular/platform-browser: 2.4.10 
@angular/platform-browser-dynamic: 2.4.10 
@angular/router: 3.4.10 
@angular/compiler-cli: 2.4.10

I am 99% sure I have the data in array and it is available to my html page.

1) console.log(Array.isArray(self.catalogue)) //true

2) I tested *ngFor just below the <ag-grid-angular> tag. It worked.

<div *ngFor='let note of catalogue'> 
    <li>{{note.Country}}</li> 
    <li>{{note.Authority}}</li> ......etc 
</div>

This post has a screenshot of what my agGrid basically looks like -- it has headers and scroll bars as if the data was printed in invisible ink. UI Grid Angular, grid renders but doesn't display data

The rowData will display if I just hard code some objects in the constructor.

constructor(private catalogueService: CatalogueService) {
 this.gridOptions = <GridOptions>{},
 this.gridOptions.columnDefs = [
 {
  headerName: "Country",
  field: "country",
  width: 200
},.....
]    
this.gridOptions.rowData = [
  {country: 'pig', authority: 'A12', banknoteID: 'bn1', pickID: 'p1', currency: 'thalers', denomination: 10},   
  ]
}

Here is my .html file

<div style="width: 1000px;">
  <ag-grid-angular #agGrid style="width: 100%; height: 200px;" 
    class="ag-fresh"
    [gridOptions]="gridOptions"
    [rowData]="catalogue">
  </ag-grid-angular>
</div>

my .ts file

import { Component, OnInit } from '@angular/core';
import { CatalogueService } from '../services/catalogue.service';
import { Catalogue } from '../models/Catalogue';
import { GridOptions } from 'ag-grid';

@Component({
  selector: 'app-ag-grid-catalogue',
  templateUrl: './ag-grid-catalogue.component.html',
  styleUrls: ['./ag-grid-catalogue.component.css']
})

export class AgGridCatalogueComponent implements OnInit {

private gridOptions: GridOptions;
private catalogue: Catalogue [];

constructor(private catalogueService: CatalogueService) {
   this.gridOptions = <GridOptions>{},
   this.gridOptions.columnDefs = [
    {
      headerName: "Country",
      field: "country",
      width: 200
    },....etc
  ]

   this.gridOptions.rowData = [ ]
  }
 //Methods
 loadCatalogue () {
   //Assign this to self to be used in callbacks
   var self = this;
     return this.catalogueService.getCatalogue().subscribe(function (data) {
        //Why can't I use dot notation to access the data param?
        //console.log(data) ==> {success: true, catalogue: Array(4)}
        if (data['success']) {
        //Bind "catalogue" to the [rowData] in the <ag-grid-angular> tag
        self.catalogue = data['catalogue']
        // tried and failed:self.gridOptions.rowData = data['catalogue'];          
        // return data['catalogue'];
       };
     })
    };

    ngOnInit () {
       this.loadCatalogue();
    };
   } 

Here is the service, but it appears that I am getting an array of JSON objects so I don't think the issue is in the service

import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';

import 'rxjs/add/operator/map';

@Injectable()
export class CatalogueService {

constructor(private http: Http) { }

private serverApi= 'http://localhost:3000';

public getCatalogue():Observable <Object> {
  // let headers = new Headers();
  // headers.append('Content-type', 'application/json');
  let URI = `${this.serverApi}` + `/`;
    return this.http.get(URI)
      .map(function (res) {
         return res.json();
      });
    }
  }

_______________________________________________________________________

====================== UPDATE per Dermo's advice ====================== _______________________________________________________________________

I still do not have access to a setRowData method.

After making your adjustments and adding a self. to one line of your code,

self.gridApi.setRowData(self.catalogue);

the console in the browser reads:

//error_handler.js:54 EXCEPTION: Cannot read property 'setRowData' of undefined

Swapping the above line of code for:

self.gridOptions.api.setRowData(self.catalogue)

ng serve compiles and there are no errors in the browser console, but... the row data is still not displayed.

Note, with a hard coded array in the this.gridOptions.rowData = [{blah, blah,...]} the grid renders that hard coded data but very quickly that data is erased and the grid is all empty rows.

It appears that neither my gridOptions object nor the gridApi object have a setRowData method on it. Should I see that method when clicking through the object shown in the browser console. I don't see any of the methods detailed in the api.docs you linked.

_______________________________________________________________________

Here are some more details (hopefully relevant.)

Before changing any code, I ran the program with a console.log inside the

loadCatalogue () {
//Assign this to self to be used in callbacks
var self = this;

return this.catalogueService.getCatalogue().subscribe(function (data) {
  if (data['success']) {        
      self.catalogue = data['catalogue']
      console.log('in cb', self)
    };
  })
};

console.log(self):
AgGridCatalogueComponent {catalogueService: CatalogueService, gridOptions: {…}, catalogue: Array(15)}
catalogue:        (15) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
catalogueService: CatalogueService {http: Http, serverApi: "http://localhost:3000"}
gridOptions:      { columnDefs: Array(11), 
                    rowData: Array(15), //(has the array of JSON objects I expected!)
                    api: GridApi,   //(with a list of properties/methods - as stated in the origainal question there is NO setRowData method)
                    columnApi: ColumnApi
                  }
__proto__:    Object

So, like you stated, the issue seems to be that the grid on the .html renders before the rowData property has been assigned a value.

Per your advice I added the 4 items to the program:

in .html

(gridReady)="onGridReady($event)"

in .ts

private gridApi;

gridApi.setRowData(self.catalogue);

onGridReady(params) {
  this.gridApi = params.api;
};

$ng serve does not compile: //Cannot find name 'gridApi' in the .ts

solution:

self.gridApi.setRowData(self.catalogue);  //Added the self. to the line of code

$ng serve now compiles, but...

console in the browser reads //error_handler.js:54 EXCEPTION: Cannot read property 'setRowData' of undefined

console.log(self):
Has one additional property: (due to the onGridReady(params) {this.gridApi = params.api;};????

gridApi:    GridApi {detailGridInfoMap: {…}, immutableService: ImmutableService, csvCreator: CsvCreator, excelCreator: null, gridCore: GridCore, …}
like image 918
Tim Avatar asked Apr 10 '18 08:04

Tim


People also ask

How to use AG-grid in Angular 2?

For using ag-grid in Angular application follow the following steps. First of all, get an angular seed project with all of the angular 2 dependencies. ….. ……… 'ag-grid-enterprise': 'node_modules/ag-grid-enterprise' First of all import GridOptions form ag-grid for setting up different properties of grid and using them in html pages.

How do I update the row data inside the grid?

Update the Row Data inside the grid by updating the rowData grid property or by calling the grid API setRowData (). The example below shows the data with two sets of data.

How to change the row model type of grid data?

Since the rowModelType is set to 'pagination', you cannot use setRowData () method to change the grid data. Instead create another local data source which sets empty data, and then use that as the data source to your grid.

How do I reset the default row data in a grid?

} The resetRowData method is quite simple, we update our bound row data variable to reference the row data we initially load into the grid. To achieve this, we use the onGridReady event to set our initial row data and a backup row data variable at the same time.


1 Answers

The problem is that ag-grid has been initialised with an empty array. You can solve this in many ways.

  • One option is to retrieve your catalogue data before loading your component.
  • Second option, detailed below, is to use the ag-grid api to set/update the
    grid data.

First of all, update your template to bind to the gridReady event

<div style="width: 1000px;">
  <ag-grid-angular #agGrid style="width: 100%; height: 200px;" 
    class="ag-fresh"
    [gridOptions]="gridOptions"
    [rowData]="catalogue"
    (gridReady)="onGridReady($event)">
  </ag-grid-angular>
</div>

Now add the onGridReady function to your .ts and add a reference to the grid api. Then set the data row in your loadCatalogue

import { Component, OnInit } from '@angular/core';
import { CatalogueService } from '../services/catalogue.service';
import { Catalogue } from '../models/Catalogue';
import { GridOptions } from 'ag-grid';

@Component({
  selector: 'app-ag-grid-catalogue',
  templateUrl: './ag-grid-catalogue.component.html',
  styleUrls: ['./ag-grid-catalogue.component.css']
})

export class AgGridCatalogueComponent implements OnInit {

private gridOptions: GridOptions;
private catalogue: Catalogue [];
private gridApi;

constructor(private catalogueService: CatalogueService) {
   this.gridOptions = <GridOptions>{},
   this.gridOptions.columnDefs = [
    {
      headerName: "Country",
      field: "country",
      width: 200
    },....etc
  ]

   this.gridOptions.rowData = [ ]
  }
 //Methods
 loadCatalogue () {
   //Assign this to self to be used in callbacks
   var self = this;
     return this.catalogueService.getCatalogue().subscribe(function (data) {
        //Why can't I use dot notation to access the data param?
        //console.log(data) ==> {success: true, catalogue: Array(4)}
        if (data['success']) {
        //Bind "catalogue" to the [rowData] in the <ag-grid-angular> tag
        self.catalogue = data['catalogue'];
        gridApi.setRowData(self.catalogue);
        // tried and failed:self.gridOptions.rowData = data['catalogue'];          
        // return data['catalogue'];
       };
     })
    };

    ngOnInit () {
       this.loadCatalogue();
    };

    onGridReady(params) {
      this.gridApi = params.api;
    };
   }

Updating grid data: https://www.ag-grid.com/javascript-grid-data-update/

Accessing api/data: https://www.ag-grid.com/javascript-grid-accessing-data/

like image 115
Dermo Avatar answered Oct 20 '22 20:10

Dermo