Can I use an async value setter in ag-Grid (TypeScript errors)?
Asked Answered
N

2

16

I am using ag-Grid with TypeScript and trying to create an async value setter in my column definition.

const columnDefs: ColDef[] = [
  {
    headerName: 'Name',
    field: 'name',
    editable: true,
    valueSetter: async (params: ValueSetterParams): Promise<boolean> => {
      return await doSomething(params); // Will return the change boolean
    }
  },
  //...other columns

But TypeScript complains that this signature is not supported because the colDef.d.ts definition file has

valueSetter?: ((params: ValueSetterParams) => boolean) | string;

However, if I just use // @ts-ignore to ignore the TypeScript error it seems to be respecting the await and my code executes in the right order.

Is it just an issue with the TypeScript definition file? Or does ag-Grid not support async value setters?

Some environment info:

  • ag-Grid 22.1.0
  • TypeScript 3.7.2
  • Aurelia (which uses WebPack, npm, etc.)
  • WebStorm 2019.3.1
Nightstick answered 9/1, 2020 at 13:29 Comment(0)
T
8

Ag-grid doesn't provide support for this, but you can still accomplish it. Instead of returning the promise, you still have to return a boolean. Then you have to manually refresh the cells after the promise returns:

valueSetter: (params: ValueSetterParams) => {
  doSomething(params).then(function() {
    params.api.refreshCells({
      rowNodes: [params.node],
      columns: [params.column]
    });
  });
  return false;
}

Here is an example, where I just use a setTimeout to emulate an async operation: https://stackblitz.com/edit/ag-grid-typescript-async-value-setter?file=src/main.ts

Transpolar answered 10/10, 2020 at 14:7 Comment(0)
L
0

I solved this issue by using a custom javascript cell renderer (React/Angular cell renderers are way slower...):

import { ICellRendererComp, ICellRendererParams } from "ag-grid-community";

export type AsyncCellParams = ICellRendererParams & { promise: (params: AsyncCellParams) => Promise<string> };

export class AsyncCellComponent implements ICellRendererComp {
  private eGui: HTMLElement;

  public getGui(): HTMLElement {
    return this.eGui;
  }

  public refresh(params: AsyncCellParams): boolean {
    return true;
  }

  public init(params: AsyncCellParams): void {
    this.eGui = document.createElement("div");
    // daisy ui skeleton
    this.eGui.innerHTML = `<div class="skeleton h-4 w-full"></div>`;
    void params.promise(params).then((value) => {
      // after promise is resolved, set the value and refresh cell
      this.eGui.innerHTML = value;
      params.refreshCell();
    });
  }
}

Usage as follows:

columnDefinition.cellRenderer = AsyncCellComponent;
columnDefinition.cellRendererParams = {
  promise: async (params: AsyncCellParams) =>
    (await this.selectViewService.getSelectViewModel(params.data[key], schemaForKey))?.label
};
Leticia answered 4/5 at 15:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.