---
title: "Client-Side Data - Single Row / Cell Updates"
framework: vue
version: "36.1.0"
---

# Client-Side Data - Single Row / Cell Updates

You can target updates to a single row or cell. Updating a single row means asking the grid to replace the data item for one specific row. Updating a cell means keeping the data item but asking the grid to replace one attribute of that data item.

Both single row and single cell updates are done by first getting a reference to the row's Row Node and then using the relevant Row Node API method. See [Accessing Data](https://www.ag-grid.com/vue-data-grid/accessing-data/) on how to access Row Nodes. Once you have access to the required Row Node, you can update its data with the following Row Node API methods:

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `updateData` | `Function` |  |  | Updates the data on the `rowNode`. When this method is called, the grid refreshes the entire rendered row if it is displayed. |
| `setData` | `Function` |  |  | Replaces the data on the `rowNode`. When this method is called, the grid refreshes the entire rendered row if it is displayed. |
| `setDataValue` | `Function` |  |  | Sets the value on the `rowNode` for the specified column and refreshes the rendered cell. In **Read Only** mode, this fires `onCellEditRequest` instead of writing directly. In **Pivot Mode**, pivot columns on leaf rows resolve to their underlying value column. The `eventSource` parameter controls how the value is written |
| `getDataValue` | `Function` |  |  | Returns the data value from the rowNode for the specified column. By default, returns committed data ignoring any pending edits. For group rows, returns aggregated values or the group key. For formula cells, returns the computed result. To get the displayed value (with formatting and value formatter applied), use `api.getCellValue()` instead. In Pivot Mode, pivot columns on leaf rows resolve to their underlying value column. The `from` parameter controls value resolution, including `'transformed'` to read the displayed [Show Values As](https://www.ag-grid.com/vue-data-grid/aggregation-show-values-as/) value. |

## Reading Cell Values

There are two ways to read cell values:

- **`rowNode.getDataValue(colKey)`** — returns the underlying data value for a column. This includes resolved valueGetters, aggregation on group rows, and computed formulas, but excludes any pending edits. Use this when you need the raw data (e.g. for calculations or external updates).
- **`api.getCellValue({ rowNode, colKey })`** — returns the display value as shown in the grid, including pending edits and group column display logic. Pass `useFormatter: true` to get the formatted string. Use this when you need the value as the user sees it.

Both methods accept an optional `from` parameter to control how pending edits are resolved — see [Batch Editing - Reading Values](https://www.ag-grid.com/vue-data-grid/cell-editing-batch/#reading-values) for details.

## View Refresh

After calling `rowNode.setData`, `rowNode.updateData` or `rowNode.setDataValue`, the grid's view automatically refreshes to reflect the change. There is no need to manually request a refresh.

The main difference between `setData` and `updateData` is that `setData` always refreshes every cell, whereas `updateData` only refreshes cells whose values have changed. Additionally, `setData` does not cause changed cells to flash when `ColDef.enableCellChangeFlash = true`.

## Sort / Filter / Group Refresh

After calling `rowNode.setData`, `rowNode.updateData` or `rowNode.setDataValue` the grid does not update to reflect a change in sorting, filtering or grouping.

To have the grid update its sort, filter or grouping call the Grid API `refreshClientSideRowModel()`.

If you want the grid to automatically update sorting, filter or grouping then you should consider using [Transaction Updates](https://www.ag-grid.com/vue-data-grid/data-update-transactions/).

## Updating Rows / Cells Example

The example below demonstrates the following:

- **Set Price on Toyota:** The price value is updated on the Toyota row and the grid refreshes the cell.
- **Set Data on Ford:** The entire data is set on the Ford row and the grid refreshes the entire row. Updated cells do not flash (even though `enableCellChangeFlash = true`).
- **Update Data on Ford:** The entire data is updated on the Ford row and the grid refreshes the changed values in the row. Updated cells flash (as `enableCellChangeFlash = true`).
- **Sort:** Re-runs the sort in the Client-Side Row Model - to see this in action, sort the data first, then edit the data so the sort is broken, then hit this button to fix the sort.
- **Filter:** Re-runs the filter in the Client-Side Row Model - to see this in action, filter the data first, then edit the data so the filter is broken (i.e. a row is present that should not be present), then hit this button to fix the filter.

#### Updating Row Nodes

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
  ClientSideRowModelApiModule,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GetRowIdFunc,
  GetRowIdParams,
  GridApi,
  GridOptions,
  GridReadyEvent,
  HighlightChangesModule,
  ModuleRegistry,
  NumberEditorModule,
  NumberFilterModule,
  RowApiModule,
  TextEditorModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  ClientSideRowModelApiModule,
  RowApiModule,
  TextEditorModule,
  TextFilterModule,
  HighlightChangesModule,
  ClientSideRowModelModule,
  NumberFilterModule,
  NumberEditorModule,
]);

function generateNewFordData() {
  const newPrice = Math.floor(window.agRandom() * 100000);
  const newModel = "T-" + Math.floor(window.agRandom() * 1000);
  return {
    id: "bb",
    make: "Ford",
    model: newModel,
    price: newPrice,
  };
}

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <div class="example-wrapper">
      <div style="margin-bottom: 1rem">
        <button v-on:click="setPriceOnToyota()">Set Price on Toyota</button>
        <button v-on:click="setDataOnFord()">Set Data on Ford</button>
        <button v-on:click="updateDataOnFord()">Update Data on Ford</button>
        <button v-on:click="updateSort()" style="margin-left: 15px">Sort</button>
        <button v-on:click="updateFilter()">Filter</button>
      </div>
      <ag-grid-vue
        style="width: 100%; height: 100%;"
        @grid-ready="onGridReady"
        :rowData="rowData"
        :columnDefs="columnDefs"
        :defaultColDef="defaultColDef"
        :getRowId="getRowId"></ag-grid-vue>
      </div>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi | null>(null);
    const rowData = ref<any[] | null>([
      { id: "aa", make: "Toyota", model: "Celica", price: 35000 },
      { id: "bb", make: "Ford", model: "Mondeo", price: 32000 },
      { id: "cc", make: "Porsche", model: "Boxster", price: 72000 },
      { id: "dd", make: "BMW", model: "5 Series", price: 59000 },
      { id: "ee", make: "Dodge", model: "Challanger", price: 35000 },
      { id: "ff", make: "Mazda", model: "MX5", price: 28000 },
      { id: "gg", make: "Horse", model: "Outside", price: 99000 },
    ]);
    const columnDefs = ref<ColDef[]>([
      { field: "make" },
      { field: "model" },
      { field: "price", filter: "agNumberColumnFilter" },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      editable: true,
      filter: true,
      enableCellChangeFlash: true,
    });
    const getRowId = ref<GetRowIdFunc>((params: GetRowIdParams) => {
      return params.data.id;
    });

    function updateSort() {
      gridApi.value!.refreshClientSideRowModel("sort");
    }
    function updateFilter() {
      gridApi.value!.refreshClientSideRowModel("filter");
    }
    function setPriceOnToyota() {
      const rowNode = gridApi.value!.getRowNode("aa")!;
      const newPrice = Math.floor(window.agRandom() * 100000);
      rowNode.setDataValue("price", newPrice);
    }
    function setDataOnFord() {
      const rowNode = gridApi.value!.getRowNode("bb")!;
      const newData = generateNewFordData();
      rowNode.setData(newData);
    }
    function updateDataOnFord() {
      const rowNode = gridApi.value!.getRowNode("bb")!;
      const newData = generateNewFordData();
      rowNode.updateData(newData);
    }
    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;
    };

    return {
      gridApi,
      rowData,
      columnDefs,
      defaultColDef,
      getRowId,
      onGridReady,
      updateSort,
      updateFilter,
      setPriceOnToyota,
      setDataOnFord,
      updateDataOnFord,
    };
  },
});

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

[Live example: Updating Row Nodes](https://www.ag-grid.com/examples/data-update-single-row-cell/updating-row-nodes/vue3)
