2

I am working on a requirement, where we want to use an AgGrid in LWC component. Below is the plain HTML code which works fine.

Plain HTML code

<!DOCTYPE HTML>
<HTML>
   <head>
    <script src="https://unpkg.com/ag-grid-community/dist/ag-grid-community.min.noStyle.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-grid.css">
    <link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-theme-alpine.css">
  </head>
  <body>
    <h1>Hello from ag-grid!</h1>
    <div id="myGrid" style="height: 600px;width:100%;" class="ag-theme-alpine"></div>
    <script type="text/javascript" charset="utf-8">
        var columnDefs = [{headerName: "Make", field: "make"},{headerName: "Model", field: "model"},{headerName: "Price", field: "price"}];
        var rowData = [{make: "Toyota", model: "Celica", price: 35000},{make: "Ford", model: "Mondeo", price: 32000},{make: "Porsche", model: "Boxter", price: 72000}];
        var gridOptions = {columnDefs: columnDefs,rowData: rowData};
        var eGridDiv = document.querySelector('#myGrid');
        new agGrid.Grid(eGridDiv, gridOptions);
   </script>
  </body>
</html>

I am trying to use the above HTML code in LWC component. Below is the LWC code.

agGrid.HTML

<template>
    <h1>Hello from ag-grid!</h1>
    <div id="myGrid" style="height: 600px;width:100%;" class="ag-theme-alpine" data-id="myGrid">
    </div>
</template>

agGrid.js

/* eslint-disable no-console */
/* eslint-disable @lwc/lwc/no-async-operation */
/* eslint-disable no-undef */
import { LightningElement } from 'lwc';
import { loadScript,loadStyle } from "lightning/platformResourceLoader";
import AgGrid from '@salesforce/resourceUrl/AgGrid';

export default class AgGridTest extends LightningElement {
columnDefs = [
    {headerName: "Make", field: "make"},
    {headerName: "Model", field: "model"},
    {headerName: "Price", field: "price"}
];

// specify the data
rowData = [
    {make: "Toyota", model: "Celica", price: 35000},
    {make: "Ford", model: "Mondeo", price: 32000},
    {make: "Porsche", model: "Boxter", price: 72000}
];

  // let the grid know which columns and what data to use
gridOptions =  {};
isCSSLoaded = false;
isAgGridCreated = false;
connectedCallback(){
    this.gridOptions = {columnDefs: this.columnDefs,rowData: this.rowData};
}

renderedCallback(){
    if (this.isCSSLoaded === false) {
        Promise.all([
            loadScript(this, AgGrid + '/ag-grid-community.js'),
            loadStyle(this, AgGrid + "/ag-grid.css"),
            loadStyle(this, AgGrid + "/ag-theme-alpine.css")
        ]);
        this.isCSSLoaded = true;
        console.log("CSS Loaded");
    }
    if(this.isAgGridCreated === false && this.isCSSLoaded === true){
        setTimeout(function(){
            console.log("Calling AgGrid");
            this.loadAgGrid();
        }.bind(this), 1000);
    }
}

loadAgGrid(){
    // lookup the container we want the Grid to use
    let eGridDiv = this.template.querySelector("div[data-id='myGrid']");
    if(eGridDiv){
        this.isAgGridCreated = true;
        // create the grid passing in the div to use together with the columns & data we want to use
        let a = new agGrid.Grid(eGridDiv, this.gridOptions);
        
    }
}
}

While running above LWC component, I am getting below error enter image description here

Note - I have included all the required JS and CSS in the static resource named as AgGrid and I also checked the same and the resources are loaded in the sources tab of browser DevTools.

Please let me know what I am doing wrong.

2
  • Hey have you got it to work? Any other grid library? – dzh Aug 18 '20 at 5:40
  • Just tried ag-grid myself. Got it loading, but it was throwing an exception (classList on undefined element). Fixed the issue in library, but it doesn't really render anything... – dzh Aug 18 '20 at 9:00
1

This is happening because the code in the below block gets executed before the script is loaded.

if(this.isAgGridCreated === false && this.isCSSLoaded === true){
    setTimeout(function(){
        console.log("Calling AgGrid");
        this.loadAgGrid();
    }.bind(this), 1000);
}

There is no guarantee that the script will be loaded before the timeout. That is why we use promises in JS. The .then(() => {}) is the success callback function of the Promise or Promise.all which gets called right after the successful execution of all jobs in the promise queue. Similarly the .catch(() => {}) is the callback function for the error.

Also, you need to call loadAgGrid() in the success callback of the Promise.all.

Promise.all([
    loadScript(this, AgGrid + '/ag-grid-community.js'),
    loadStyle(this, AgGrid + "/ag-grid.css"),
    loadStyle(this, AgGrid + "/ag-theme-alpine.css")
])
    .then(() => {
        this.isCSSLoaded = true;
        this.loadAgGrid();
    })
    .catch(error => {
        // handle error
    });

With this approach, you don't even need to set a Timeout.

Learn more about promises.

More details on How to load third party js in Lwc

2
  • Thanks for the reply. I tried with adding promises in JS. But still, I am getting the same error. – Hemant Keni Jul 1 '20 at 9:15
  • @HemantKeni Can you please add the updated code in question? Also, make sure if the relative URLs for the static resources are correct. – Rahul Gawale Jul 1 '20 at 9:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.