---
product: "AG Grid"
title: "Client-Side Data - Single Row / Cell Updates"
description: "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."
framework: javascript
version: "36.2.0"
related:
    - title: "Row Data"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/data-update-row-data/"
    - title: "Transactions"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/data-update-transactions/"
    - title: "High Frequency"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/data-update-high-frequency/"
llms: "https://www.ag-grid.com/archive/36.2.0/llms.txt"
---

# 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/archive/36.2.0/javascript-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` |  |  |  |
| `setData` | `Function` |  |  |  |
| `setDataValue` | `Function` |  |  |  |
| `getDataValue` | `Function` |  |  |  |

## 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/archive/36.2.0/javascript-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/archive/36.2.0/javascript-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 {
  ClientSideRowModelApiModule,
  ClientSideRowModelModule,
  GetRowIdParams,
  GridApi,
  GridOptions,
  HighlightChangesModule,
  ModuleRegistry,
  NumberEditorModule,
  NumberFilterModule,
  RowApiModule,
  TextEditorModule,
  TextFilterModule,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

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

const rowData = [
  { 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 },
];

let gridApi: GridApi;

const gridOptions: GridOptions = {
  columnDefs: [
    { field: "make" },
    { field: "model" },
    { field: "price", filter: "agNumberColumnFilter" },
  ],
  defaultColDef: {
    flex: 1,
    editable: true,
    filter: true,
    enableCellChangeFlash: true,
  },
  getRowId: (params: GetRowIdParams) => {
    return params.data.id;
  },
  rowData: rowData,
};

function updateSort() {
  gridApi!.refreshClientSideRowModel("sort");
}

function updateFilter() {
  gridApi!.refreshClientSideRowModel("filter");
}

function setPriceOnToyota() {
  const rowNode = gridApi!.getRowNode("aa")!;
  const newPrice = Math.floor(window.agRandom() * 100000);
  rowNode.setDataValue("price", newPrice);
}

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,
  };
}

function setDataOnFord() {
  const rowNode = gridApi!.getRowNode("bb")!;
  const newData = generateNewFordData();
  rowNode.setData(newData);
}

function updateDataOnFord() {
  const rowNode = gridApi!.getRowNode("bb")!;
  const newData = generateNewFordData();
  rowNode.updateData(newData);
}

// wait for the document to be loaded, otherwise
// AG Grid will not find the div in the document.
const eGridDiv = document.querySelector<HTMLElement>("#myGrid")!;
gridApi = createGrid(eGridDiv, gridOptions);

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

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