Clue Mediator

How to add a loading in React AG Grid

📅July 3, 2021

Today we’ll show you how to add a loading in React AG Grid.

In the previous article, we have implement server side pagination in React AG Grid. Here, we'll show you how to show loading during an API call and how to hide it after receiving a response.

Checkout more articles on ReactJS

Demo Application

Output - How to add a loading in React AG Grid - Clue Mediator

Output - How to add a loading in React AG Grid - Clue Mediator

Steps to add a loading in AG Grid

  1. Load data using API in AG Grid
  2. Add loading in Grid
  3. Output

1. Load data using API in AG Grid

First of all, we have to implement the React AG Grid and integrate the API in AG Grid. Check the following article to implement server-side pagination in React AG Grid.

Implement server side pagination in React AG Grid

App.js

import React, { useEffect, useState } from 'react';
import { AgGridColumn, AgGridReact } from 'ag-grid-react';

import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';

import './App.css';

function App() {
  const [gridApi, setGridApi] = useState(null);
  const perPage = 3;

  const onGridReady = (params) => {
    setGridApi(params.api);
  };

  useEffect(() => {
    if (gridApi) {
      const dataSource = {
        getRows: (params) => {
          // Use startRow and endRow for sending pagination to Backend
          // params.startRow : Start Page
          // params.endRow : End Page

          const page = params.endRow / perPage;
          fetch(`https://reqres.in/api/users?per_page=${perPage}&page=${page}`)
            .then(resp => resp.json())
            .then(res => {
              params.successCallback(res.data, res.total);
            }).catch(err => {
              params.successCallback([], 0);
            });
        }
      }

      gridApi.setDatasource(dataSource);
    }
  }, [gridApi]);

  const avatarFormatter = ({ value }) => {
    return <img src={value} width="50px" height="50px">
  }

  return (
    <div class="App">
      <h2>Add a loading in React AG Grid - <a href="https://www.cluemediator.com" target="_blank" rel="noopener">Clue Mediator</a></h2>
      <div class="ag-theme-alpine ag-style">
        <aggridreact 1="" pagination={true} rowmodeltype={'infinite'} paginationpagesize={perPage} cacheblocksize={perPage} ongridready={onGridReady} rowheight={60} defaultcoldef={{ flex: }}>
          <aggridcolumn field="first_name" headername="First Name" cellclass="vertical-middle">
          <aggridcolumn field="last_name" headername="Last Name" cellclass="vertical-middle">
          <aggridcolumn field="email" headername="Email" cellclass="vertical-middle">
          <aggridcolumn field="avatar" headername="Avatar" cellrendererframework={avatarFormatter} cellclass="vertical-middle">
        </aggridcolumn></aggridcolumn></aggridcolumn></aggridcolumn></aggridreact>
      </div>
    </div>
  );
}

export default App;

2. Add loading in Grid

We will use the overlay to add the loading indicator in the Grid.

There are two types of the overlay for the grid.

  • Loading: Gets displayed when the grid is loading data.
  • No Rows: Gets displayed when loading has completed but no rows to show.

Use the following methods for overlays.

  • To show loading overlay: `gridApi.showLoadingOverlay();`
  • To show no rows overlay: `gridApi.showNoRowsOverlay();`
  • To clear all overlays: `gridApi.hideOverlay();`

We can also add the custom template using the `overlayLoadingTemplate` and `overlayNoRowsTemplate`. Check the following code to show/hide a loading template.

...
...

function App() {

  useEffect(() => {
    if (gridApi) {
      const dataSource = {
        getRows: (params) => {
          // Use startRow and endRow for sending pagination to Backend
          // params.startRow : Start Page
          // params.endRow : End Page

          gridApi.showLoadingOverlay();
          const page = params.endRow / perPage;
          fetch(`https://reqres.in/api/users?per_page=${perPage}&page=${page}`)
            .then(resp => resp.json())
            .then(res => {
              if (!res.data.length) {
                gridApi.showNoRowsOverlay();
              }
              else {
                gridApi.hideOverlay();
              }
              params.successCallback(res.data, res.total);
            }).catch(err => {
              gridApi.showNoRowsOverlay();
              params.successCallback([], 0);
            });
        }
      }

      gridApi.setDatasource(dataSource);
    }
  }, [gridApi]);

  return (
    <div class="App">
      ...
      ...
      <div class="ag-theme-alpine ag-style">
        <aggridreact ...="" overlayloadingtemplate="{" '<span="" class="ag-overlay-loading-center">Please wait while your rows are loading...'
          }
          overlayNoRowsTemplate={
            '<span class="ag-overlay-loading-center">No data found to display.</span>'
          }
        >
          ...
          ...
        </aggridreact>
      </div>
    </div>
  );
}

export default App;

3. Output

Let’s combine all the code together and see how it looks.

App.js

import React, { useEffect, useState } from 'react';
import { AgGridColumn, AgGridReact } from 'ag-grid-react';

import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';

import './App.css';

function App() {
  const [gridApi, setGridApi] = useState(null);
  const perPage = 3;

  const onGridReady = (params) => {
    setGridApi(params.api);
  };

  useEffect(() => {
    if (gridApi) {
      const dataSource = {
        getRows: (params) => {
          // Use startRow and endRow for sending pagination to Backend
          // params.startRow : Start Page
          // params.endRow : End Page

          gridApi.showLoadingOverlay();
          const page = params.endRow / perPage;
          fetch(`https://reqres.in/api/users?per_page=${perPage}&page=${page}`)
            .then(resp => resp.json())
            .then(res => {
              if (!res.data.length) {
                gridApi.showNoRowsOverlay();
              }
              else {
                gridApi.hideOverlay();
              }
              params.successCallback(res.data, res.total);
            }).catch(err => {
              gridApi.showNoRowsOverlay();
              params.successCallback([], 0);
            });
        }
      }

      gridApi.setDatasource(dataSource);
    }
  }, [gridApi]);

  const avatarFormatter = ({ value }) => {
    return <img src={value} width="50px" height="50px">
  }

  return (
    <div class="App">
      <h2>Add a loading in React AG Grid - <a href="https://www.cluemediator.com" target="_blank" rel="noopener">Clue Mediator</a></h2>
      <div class="ag-theme-alpine ag-style">
        <aggridreact 1="" pagination={true} rowmodeltype={'infinite'} paginationpagesize={perPage} cacheblocksize={perPage} ongridready={onGridReady} rowheight={60} defaultcoldef={{ flex: }} overlayloadingtemplate="{" '<span="" class="ag-overlay-loading-center">Please wait while your rows are loading...'
          }
          overlayNoRowsTemplate={
            '<span class="ag-overlay-loading-center">No data found to display.</span>'
          }
        >
          <aggridcolumn field="first_name" headername="First Name" cellclass="vertical-middle">
          <aggridcolumn field="last_name" headername="Last Name" cellclass="vertical-middle">
          <aggridcolumn field="email" headername="Email" cellclass="vertical-middle">
          <aggridcolumn field="avatar" headername="Avatar" cellrendererframework={avatarFormatter} cellclass="vertical-middle">
        </aggridcolumn></aggridcolumn></aggridcolumn></aggridcolumn></aggridreact>
      </div>
    </div>
  );
}

export default App;

Run the application and check the output in the browser.

I hope you find this article helpful.
Thank you for reading. Happy Coding..!! 🙂

Demo & Source Code

GitHub Repository StackBlitz Project