I am trying to update ag-grid, after cell values change in bulk instead of one value at a time. I know there's already a method (cellvaluechanged) that gives you what value has been changed along with api and colDef. I also tried pasteEnd from ag-grid but this just works for paste, what if user just edits the cell value without copy pasting. What I am trying to do is have a method which will be called after a second or two, grabing all the values changed within ag-grid to avoid multiple rounds to backend. Possible Extension of this question: How to launch a method after a cell value has been edited in ag-grid?
Html
<ag-grid-angular [ngStyle]="{'height.px': innerHeight}" #agGridLevel class="ag-theme-balham"
[rowData]="rowData" [gridOptions]="gridOptions" [defaultColDef]="defaultColDef" [sideBar]="sideBar"
[columnDefs]="columnDefs" [excelStyles]="excelStyles" [rowSelection]="'multiple'"
(selectionChanged)="onSelectionChanged()" (rowClicked)="onRowClicked($event)"
[suppressCopyRowsToClipboard]="true"
[enableRangeSelection]="true"
(cellValueChanged)="onCellValueChanged($event)"
(gridReady)="onGridReady($event)">
>
</ag-grid-angular>
component.ts file
P.S. I know the method would still call backend multiple times even with timeout. This was just to show what I was trying to do.
onCellValueChanged(params) {
console.log("Callback onCellValueChanged:", params);
if (params.newValue) {
this.changedValue.push({
field: params.colDef.field,
newValue: params.newValue.trim(),
id: params.data.id
});
setTimeout(() => {
this.updateCellValuesInDb(this.changedValue)
}, 1000);
}
}
Would help a lot if someone knows how to bulk load the whole cell values changed after a second or two instead of sending every single value changed. Please advice.
Thank you
I was able to use Interval based on comments. What happens is once the cell value changes, onCellValueChanged event is fired, from which I get changed value, Id of the row along with the actual field name. setTimeout() on the values changed just in case if there's 10-20 values pasted together to avoid back and forth backend calls.
Update CellValue then sets interval(500).
In the final step, isCellValueUpdated boolean declared as false in the component will handle the multiple calls to backend and bulk load will be done once per actual request for multiple records.
onCellValueChanged(params) {
console.log('Callback onCellValueChanged:', params);
if (params.newValue) {
this.changedValue.push({
field: params.colDef.field,
newValue: params.newValue.trim(),
id: params.data.id
});
setTimeout(() => {
this.updateCellValues(this.changedValue);
}, 1000);
}
}
private updateCellValues(values: IGridChangedValues[]) {
const changeBooleanAfterValuesChange = interval(500);
this.updateDb({ values, changeBooleanAfterValuesChange });
}
private updateDb(
{ values, changeBooleanAfterValuesChange }:
{ values: IGridChangedValues[]; changeBooleanAfterValuesChange: Observable<number>; }) {
if (!this.isCellValueUpdated) {
this.isCellValueUpdated = true;
this._studyLevelService.updateCellValuesInDb(values).pipe(takeUntil(this.unsubscribe$)).subscribe(
(result: boolean) => {
if (result) {
} else {
this._dialogs.alert(new AlertDialogOptions(
'Error',
'Error Updating values'));
}
changeBooleanAfterValuesChange.pipe(takeUntil(this.unsubscribe$)).subscribe(
() => this.isCellValueUpdated = false
)
})
}
}
I was hoping there might be a better solution out there to avoid intervals and timeouts, but I think that's the best technique available for ag-grid right now