---
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: angular
version: "36.2.0"
related:
    - title: "Row Data"
      url: "https://www.ag-grid.com/archive/36.2.0/angular-data-grid/data-update-row-data/"
    - title: "Transactions"
      url: "https://www.ag-grid.com/archive/36.2.0/angular-data-grid/data-update-transactions/"
    - title: "High Frequency"
      url: "https://www.ag-grid.com/archive/36.2.0/angular-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/angular-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/angular-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/angular-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 { Component } from "@angular/core";
import { AgGridAngular } from "ag-grid-angular";
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") {
  // Enable extended validations only for development
  enableDevValidations();
}

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

@Component({
  selector: "my-app",
  standalone: true,
  imports: [AgGridAngular],
  template: `<div class="example-wrapper">
    <div style="margin-bottom: 1rem">
      <button (click)="setPriceOnToyota()">Set Price on Toyota</button>
      <button (click)="setDataOnFord()">Set Data on Ford</button>
      <button (click)="updateDataOnFord()">Update Data on Ford</button>
      <button (click)="updateSort()" style="margin-left: 15px">Sort</button>
      <button (click)="updateFilter()">Filter</button>
    </div>
    <ag-grid-angular
      style="width: 100%; height: 100%;"
      [rowData]="rowData"
      [columnDefs]="columnDefs"
      [defaultColDef]="defaultColDef"
      [getRowId]="getRowId"
      (gridReady)="onGridReady($event)"
    />
  </div> `,
})
export class AppComponent {
  private gridApi!: GridApi;

  rowData: 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 },
  ];
  columnDefs: ColDef[] = [
    { field: "make" },
    { field: "model" },
    { field: "price", filter: "agNumberColumnFilter" },
  ];
  defaultColDef: ColDef = {
    flex: 1,
    editable: true,
    filter: true,
    enableCellChangeFlash: true,
  };
  getRowId: GetRowIdFunc = (params: GetRowIdParams) => {
    return params.data.id;
  };

  updateSort() {
    this.gridApi.refreshClientSideRowModel("sort");
  }

  updateFilter() {
    this.gridApi.refreshClientSideRowModel("filter");
  }

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

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

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

  onGridReady(params: GridReadyEvent) {
    this.gridApi = params.api;
  }
}

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

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