---
title: "Async Data"
framework: javascript
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

```ts
import {
  AgFieldDefinition,
  AgReportState,
  AgStudioApi,
  AgStudioProperties,
  createStudio,
} from "ag-studio";

const initialState: AgReportState = {
  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,
    },
  },
};

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 studioProperties: AgStudioProperties = {
  mode: "edit",
  initialState,
  data: {
    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,
          },
        ],
      },
    ],
  },
};

let studioApi: AgStudioApi;

// setup Studio after the page has finished loading
const studioDiv = document.querySelector<HTMLElement>("#myStudio")!;
studioApi = createStudio(studioDiv, studioProperties);
```

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

```js
const studioProperties = {
    data: {
        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
            ],
        }],
    },

    // other studio properties ...
}
```

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/javascript/data#relationships).

## Reloading Data

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

#### Reloading Data

```ts
import {
  AgFieldDefinition,
  AgReportState,
  AgStudioApi,
  AgStudioProperties,
  createStudio,
} from "ag-studio";

const initialState: AgReportState = {
  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 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",
  },
];

async function loadData(): Promise<Record<string, any>[]> {
  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();

function reload() {
  dataPromise = loadData();
  studioApi.reload();
}

const studioProperties: AgStudioProperties = {
  mode: "edit",
  initialState,
  data: {
    sources: [
      {
        id: "medalsSource",
        dataShape: "row",
        getData: async () => ({ data: await dataPromise }),
        tables: [
          {
            id: "medals",
            fields,
          },
        ],
      },
    ],
  },
};

let studioApi: AgStudioApi;

// setup Studio after the page has finished loading
const studioDiv = document.querySelector<HTMLElement>("#myStudio")!;
studioApi = createStudio(studioDiv, studioProperties);

if (typeof window !== "undefined") {
  // Attach external event handlers to window so they can be called from index.html
  (<any>window).reload = reload;
}
```

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