---
title: "Async Data"
framework: react
version: "2.1.2"
---

# Async Data

Asynchronous data sources can be used to lazy load data on demand.

An asynchronous data source represents one or more tables of data.

#### Asynchronous Data Source

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgStudio, AgStudioRef } from "ag-studio-react";
import {
  AgDataEngine,
  AgDataSourcesDefinition,
  AgFieldDefinition,
  AgReportState,
  AgStudioApi,
  AgStudioMode,
  AgStudioProperties,
} from "ag-studio";

const fields: AgFieldDefinition[] = [
  {
    id: "athlete",
    format: "textFormat",
  },
  {
    id: "age",
    format: "integerFormat",
  },
  {
    id: "country",
    format: "textFormat",
  },
  {
    id: "year",
    format: "integerFormat",
    formatOptions: { format: "0" },
  },
  {
    id: "date",
    format: "dateFormat",
  },
  {
    id: "sport",
    format: "textFormat",
  },
  {
    id: "gold",
    format: "integerFormat",
  },
  {
    id: "silver",
    format: "integerFormat",
  },
  {
    id: "bronze",
    format: "integerFormat",
  },
  {
    id: "total",
    format: "integerFormat",
  },
];

const StudioExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const studioStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
  const [data, setData] = useState<AgDataSource>({
    sources: [
      {
        id: "medalsSource",
        dataShape: "row",
        getData: async () => {
          const response = await fetch(
            "https://www.ag-grid.com/studio/example-assets/olympic-winners.json",
          );
          const data = await response.json();
          return { data };
        },
        tables: [
          {
            id: "medals",
            fields,
          },
        ],
      },
    ],
  });
  const initialState = useMemo<AgReportState>(() => {
    return {
      pages: [
        {
          id: "page1",
          widgets: {
            "1": {
              type: "grid",
              dataMapping: {
                cols: [
                  { id: "medals.country" },
                  { id: "medals.sport" },
                  { id: "medals.gold", aggregation: "sum" },
                  { id: "medals.silver", aggregation: "sum" },
                  { id: "medals.bronze", aggregation: "sum" },
                  { id: "medals.total", aggregation: "sum" },
                ],
              },
            },
            "2": {
              type: "column-chart-grouped",
              dataMapping: {
                categoryKey: [{ id: "medals.country" }],
                valueKey: [
                  { id: "medals.gold", aggregation: "sum" },
                  { id: "medals.silver", aggregation: "sum" },
                  { id: "medals.bronze", aggregation: "sum" },
                ],
                tooltipKey: [],
              },
            },
          },
          widgetLayout: {
            "1": {
              xTrack: 0,
              yTrack: 0,
              xSpan: 24,
              ySpan: 16,
            },
            "2": {
              xTrack: 0,
              yTrack: 16,
              xSpan: 24,
              ySpan: 16,
            },
          },
        },
      ],
      selectedPageId: "page1",
      panels: {
        filters: {
          collapsed: true,
        },
        edit: {
          collapsed: true,
        },
      },
    };
  }, []);

  return (
    <div style={containerStyle}>
      <div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
        <AgStudio
          style={studioStyle}
          className="my-studio-container"
          data={data}
          initialState={initialState}
          mode={"edit"}
        />
      </div>
    </div>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <StudioExample />
  </StrictMode>,
);
```

[Live example: Asynchronous Data Source](https://www.ag-grid.com/studio/examples/async-data/async-data-source/reactFunctionalTs/)

```jsx
const data = useMemo(() => { 
	return {
        sources: [{
            id: 'medalsSource',
            dataShape: 'row',
            getData: async (tableId) => {
                const data = await fetchData(tableId);
                return { data };
            },
            tables: [
                {
                    id: 'medals',
                    fields: [
                        {
                            id: 'athlete',
                            format: 'textFormat',
                        },
                        // ... other fields
                    ],
                },
                // ... other tables
            ],
        }],
    };
}, []);

<AgStudio data={data} />
```

Asynchronous data sources can return row-based or column-based data. This is determined by the `dataShape` property.

Properties available on the `AgDataSourceDefinition&lt;TDataShape extends AgDataShape, TRegistry extends AgBaseRegistry = AgDefaultRegistry&gt;` interface.

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `id` | `string` |  | Data source ID |
| `name` | `string` |  | Data source display name. If not provided, a formatted version of `id` will be used. |
| `getData` | `Function` |  | Callback to return the data for the provided table and fields |
| `dataShape` | `TDataShape` |  | `'row'` if the data is row-based, or `'column'` if the data is column-based. |
| `tables` | `AgAsyncTableDefinition<TRegistry>[]` |  | One or more tables that are provided by this data source. |

## Multiple Tables

When multiple tables are provided, they can be linked by providing [Relationships](https://www.ag-grid.com/studio/react/data#relationships).

## Reloading Data

Data can be reloaded by calling `api.reload()`.

#### Reloading Data

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgStudio, AgStudioRef } from "ag-studio-react";
import {
  AgDataEngine,
  AgDataSourcesDefinition,
  AgFieldDefinition,
  AgReportState,
  AgStudioApi,
  AgStudioMode,
  AgStudioProperties,
} from "ag-studio";

const fields: AgFieldDefinition[] = [
  {
    id: "athlete",
    format: "textFormat",
  },
  {
    id: "country",
    format: "textFormat",
  },
  {
    id: "year",
    format: "integerFormat",
    formatOptions: { format: "0" },
  },
  {
    id: "sport",
    format: "textFormat",
  },
  {
    id: "gold",
    format: "integerFormat",
  },
  {
    id: "silver",
    format: "integerFormat",
  },
  {
    id: "bronze",
    format: "integerFormat",
  },
];

const loadData: () => Promise<Record<string, any>[]> = async () => {
  const response = await fetch(
    "https://www.ag-grid.com/studio/example-assets/olympic-winners.json",
  );
  const sourceData = await response.json();
  return sourceData
    .slice(
      Math.floor(window.agRandom() * 100),
      200 + Math.floor(window.agRandom() * 100),
    )
    .map((row: any) => ({
      ...row,
      gold: Math.floor(window.agRandom() * 3),
      silver: Math.floor(window.agRandom() * 4),
      bronze: Math.floor(window.agRandom() * 4),
    }));
};

let dataPromise: Promise<Record<string, any>[]> = loadData();

const StudioExample = () => {
  const studioRef = useRef<AgStudioRef>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const studioStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
  const [data, setData] = useState<AgDataSource>({
    sources: [
      {
        id: "medalsSource",
        dataShape: "row",
        getData: async () => ({ data: await dataPromise }),
        tables: [
          {
            id: "medals",
            fields,
          },
        ],
      },
    ],
  });
  const initialState = useMemo<AgReportState>(() => {
    return {
      pages: [
        {
          id: "page1",
          widgets: {
            "1": {
              type: "grid",
              dataMapping: {
                cols: [
                  { id: "medals.country" },
                  { id: "medals.sport" },
                  { id: "medals.gold", aggregation: "sum" },
                  { id: "medals.silver", aggregation: "sum" },
                  { id: "medals.bronze", aggregation: "sum" },
                ],
              },
            },
            "2": {
              type: "column-chart-grouped",
              dataMapping: {
                categoryKey: [{ id: "medals.country" }],
                valueKey: [
                  { id: "medals.gold", aggregation: "sum" },
                  { id: "medals.silver", aggregation: "sum" },
                  { id: "medals.bronze", aggregation: "sum" },
                ],
                tooltipKey: [],
              },
            },
          },
          widgetLayout: {
            "1": {
              xTrack: 0,
              yTrack: 0,
              xSpan: 24,
              ySpan: 16,
            },
            "2": {
              xTrack: 0,
              yTrack: 16,
              xSpan: 24,
              ySpan: 16,
            },
          },
        },
      ],
      selectedPageId: "page1",
      panels: {
        filters: {
          collapsed: true,
        },
        edit: {
          collapsed: true,
        },
      },
    };
  }, []);

  const reload = useCallback(() => {
    dataPromise = loadData();
    studioRef.current!.api.reload();
  }, []);

  return (
    <div style={containerStyle}>
      <div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
        <div className="example-controls">
          <div className="controls-row">
            <button id="reload" onClick={reload}>
              Reload
            </button>
          </div>
        </div>

        <AgStudio
          ref={studioRef}
          style={studioStyle}
          className="my-studio-container"
          data={data}
          initialState={initialState}
          mode={"edit"}
        />
      </div>
    </div>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <StudioExample />
  </StrictMode>,
);
```

[Live example: Reloading Data](https://www.ag-grid.com/studio/examples/async-data/async-data-reload/reactFunctionalTs/)
