---
title: "Async Data"
framework: vue
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 {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgStudio } from "ag-studio-vue3";
import {
  AgDataEngine,
  AgDataSourcesDefinition,
  AgFieldDefinition,
  AgReportState,
  AgStudioApi,
  AgStudioApiReadyEvent,
  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 VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <div style="display: flex; flex-direction: column; height: 100%">
      <ag-studio
        style="width: 100%; height: 100%;"
        class="my-studio-container"
        @api-ready="onApiReady"
        :initialState="initialState"
        :mode="mode"
        :data="data"></ag-studio>
      </div>
        </div>
    `,
  components: {
    "ag-studio": AgStudio,
  },
  setup(props) {
    const studioApi = shallowRef<AgStudioApi | null>(null);
    const initialState = ref<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 mode = ref<AgStudioMode>("edit");
    const data = ref<AgDataSourcesDefinition | AgDataEngine>({
      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 onApiReady = (params: AgStudioApiReadyEvent) => {
      studioApi.value = params.api;
    };

    return {
      studioApi,
      initialState,
      mode,
      data,
      onApiReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

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

```ts
<ag-studio
    :data="data"
    /* other studio properties ... */>
</ag-studio>

this.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
        ],
    }],
};
```

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

## Reloading Data

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

#### Reloading Data

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgStudio } from "ag-studio-vue3";
import {
  AgDataEngine,
  AgDataSourcesDefinition,
  AgFieldDefinition,
  AgReportState,
  AgStudioApi,
  AgStudioApiReadyEvent,
  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",
  },
];

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();

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <div style="display: flex; flex-direction: column; height: 100%">
      <div class="example-controls">
        <div class="controls-row">
          <button id="reload" v-on:click="reload()">Reload</button>
        </div>
      </div>
      <ag-studio
        style="width: 100%; height: 100%;"
        class="my-studio-container"
        @api-ready="onApiReady"
        :initialState="initialState"
        :mode="mode"
        :data="data"></ag-studio>
      </div>
        </div>
    `,
  components: {
    "ag-studio": AgStudio,
  },
  setup(props) {
    const studioApi = shallowRef<AgStudioApi | null>(null);
    const initialState = ref<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 mode = ref<AgStudioMode>("edit");
    const data = ref<AgDataSourcesDefinition | AgDataEngine>({
      sources: [
        {
          id: "medalsSource",
          dataShape: "row",
          getData: async () => ({ data: await dataPromise }),
          tables: [
            {
              id: "medals",
              fields,
            },
          ],
        },
      ],
    });

    function reload() {
      dataPromise = loadData();
      studioApi.value.reload();
    }
    const onApiReady = (params: AgStudioApiReadyEvent) => {
      studioApi.value = params.api;
    };

    return {
      studioApi,
      initialState,
      mode,
      data,
      onApiReady,
      reload,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

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