GridComponent not refreshing

I have wrapped the GridComponent in a React functional component.
The datasource is set by props.
When I change the datasource from a parent component, the displayed data changes, but the columns do not.
How do I force a refresh of column definitions when the datasource changes?

Current Code (abbreviated):
```
/* eslint-disable react/jsx-props-no-spreading */
/* eslint-disable react/jsx-boolean-value */
/* eslint-disable no-return-assign */
/* eslint-disable no-nested-ternary */
/* eslint-disable react/prop-types */
/* eslint-disable react/destructuring-assignment */
import React from 'react';
import { GridComponent, ColumnsDirective, ColumnDirective, Inject, Sort, Resize, Filter, Group, Toolbar, ToolbarItems, ExcelExport, ColumnChooser, } from '@syncfusion/ej2-react-grids';
import styled from 'styled-components';
import { MYSQL_TYPE, DATASET_TYPE } from '../sql/data_type_constants';

const Styles = styled.div`
  .e-grid * {
    font-size12px !important;
  }
  .e-grid .e-content {
    overflow-yauto !important;
  }
  .e-checkbox-wrapper .e-frame,
  .e-css.e-checkbox-wrapper .e-frame {
    border1px solid white;
    height16px;
    width16px;
  }
  .e-checkbox-wrapper .e-frame.e-check,
  .e-css.e-checkbox-wrapper .e-frame.e-check {
    padding-top2px;
    background-color#00b0ff;
    border-colorwhite;
    colorwhite !important;
  }
  .e-checkbox-wrapper:hover .e-frame.e-check,
  .e-css.e-checkbox-wrapper:hover .e-frame.e-check {
    padding-top2px;
    background-color#0090aa;
    border-colorwhite;
    colorwhite !important;
  }
  .e-grid .e-headercell {
    padding-right8px;
  }
`;

const createColumnDefinitionJson = (field, key=> {
  const format = { width'80' };
  return <ColumnDirective key={key} {...format} field={field} />;
  // not shown for brevity
};

const createColumnDefinitionSQL = (field, key=> {
  // code omitted for brevity.........
  const format = { width'80' };
  return <ColumnDirective key={key} {...format} field={field.name} />;
};

const createTableColumns = (dataFields, datasetType=> {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  if (dataFields.length === 0) {
    console.log('NO FIELDS TO CREATE');
    return '';
  }
  console.log('CREATING FIELDS');
  const results = (
    <ColumnsDirective key="any1">
      <ColumnDirective type="checkbox" width="50" />
      {dataFields.map((field, i=>
        datasetType === DATASET_TYPE.JSON
          ? createColumnDefinitionJson(field, i)
          : createColumnDefinitionSQL(field, i)
      )}
    </ColumnsDirective>
  );

  return results;
};

/**
 * Main DataGrid functional component.
 * Receives props:
 * if JSON fields are extracted from the first row of the datasource
 * if SQL fields are provided to props.dataFields
 */
const DataGrid = (props=> {
  // extract the data from props. Handle differently based on "datasetType"
  let grid;
  const toolbarOptions = ['ExcelExport''ColumnChooser''Update'];

  const dataBound = () => {
    if (grid) {
      console.log('DATABOUND');
    }
  };

  const handleRefresh = () => {
    console.log('about to refresh');
    if (grid) {
      console.log('refreshing');
      grid.refresh();
    }
  };

  if (grid) {
    console.log('REFRESHING');
  }

  return (
    <Styles style={width'100%'height'100%' }}>
      <GridComponent
        dataSource={props.dataSource}
        dataBound={dataBound}
        dataSourceChanged={handleRefresh}
        ref={(g=> (grid = g)}
        height="100%"
        width="100%"
        showColumnChooser={true}
        rowHeight="28"
        resizeSettings={mode'Normal' }}
        toolbar={toolbarOptions}
        allowExcelExport={true}
        allowMultiSorting={true}
        allowResizing={true}
        allowSorting={true}
        filterSettings={type'Menu' }}
        allowFiltering={true}
        allowSelection={true}
        allowGrouping={true}
        selectionSettings={type'Multiple'mode'Both' }}
      >
        <Inject
          services={[
            Resize,
            Filter,
            Sort,
            Group,
            Toolbar,
            ExcelExport,
            ColumnChooser,
          ]}
        />
        {createTableColumns(props.dataFields, props.datasetType)}
      </GridComponent>
    </Styles>
  );
};

export default DataGrid;
```



4 Replies 1 reply marked as answer

SU Suresh January 15, 2021 06:53 PM UTC

I am 90% sure this is a bug.
Here's an easy way of reproducing.
  1. Send the grid a json datasource with data. It works as expected.
  2. Now send the grid a datasource of undefined, or null or [] or [{}]
  3. Now send the grid the first datasource again.
The grid shows no rows, but columns are not destroyed and the prior columns remain. Further, when the original dataset is resent, all column formatting is lost.
My workaround is silly. I create a single checkbox column even when the dataset is empty.

  • The bug is that the grid is not clearing and rebuilding columns when the datasource has no columns (i.e. undefined, or null or [] or [{}])




PG Praveenkumar Gajendiran Syncfusion Team January 18, 2021 02:57 PM UTC

Hi Suresh, 
Thanks for contacting Syncfusion support.

We checked your query and provided information. In that we found you have using auto-generating column to the Grid and change the Grid dataSource dynamically.  

For this we would like to inform you that the generated columns will be bind to the Grid at the initial rendering and if you change the Grid dataSource dynamically, it will not affect the Grid columns, it only affect the Grid dataSource.  

If you want to change the Grid columns, you need to dynamically update the new columns to the Grid as demonstrated in the below code example and
it will not affect the Grid dataSource.

 
gridObject.columns= [{field: "OrderID", headerText: "Order ID"}, {field: "CustomerID", headerText: "Customer ID"},]

 

API Link: https://ej2.syncfusion.com/react/documentation/api/grid/#columns

Sample: https://stackblitz.com/edit/react-tlqc8c?file=index.js

So please explain your exact requirement with more details and share the video demonstration of your requirement, that will be helpful for us to proceed further.

Regards,
Praveenkumar G  



SU Suresh January 18, 2021 11:19 PM UTC

I think you are missing my issue.
Let me make it really simple.
  1. Let us say I have a grid that is given a valid DataSource and correctly displays the data and columns.
  2. Now let's say I want to reset the grid to a blank state. No Columns. No rows.
How do I do #2? Setting the datasource to null; and empty object or whatever, doesn't work. 


PG Praveenkumar Gajendiran Syncfusion Team January 19, 2021 01:06 PM UTC

Hi Suresh, 
 
Thanks for your update. 
 
We checked your query and based on that suspect that your requirement is to empty the Grid columns also along with the Grid dataSource. You can achieve this by setting an empty array to the Grid columns property in the dataBound event when the dataSource is emptied(which can be checked using a global flag variable). This is demonstrated in the below code example, 

btnClick1() { 
    this.grid.dataSource = []; // Here we set the empty array to grid dataSource 
    this.flag = true;        // Flag variable 
 
dataBound() { // Grid’s dataBound event handler 
    if (this.flag) { // This event will be triggered each time the grid data is modified, so flag variable is used so that this case is executed only on emptying the grid dataSource. 
      this.grid.columns = []; // Then the grid columns are emptied 
      this.flag = false; 
    } 

Please find the below sample prepared based on this for your reference, 


If you still face the issue, share us a simple sample to replicate the problem or try reproducing it in the above provided sample and video demonstration of your issue. It would be helpful to identify your problem case better so that we can check and provide the solution based on that. 

Regards, 
Praveenkumar G 


Marked as answer
Loader.
Up arrow icon