From ab6a9bbac29a2caf34f4dd8211cd18116f659804 Mon Sep 17 00:00:00 2001 From: Michael Kret <88898367+michael-radency@users.noreply.github.com> Date: Thu, 19 Oct 2023 14:54:13 +0300 Subject: [PATCH] fix(Google Sheets Node): Append or update runs forever when without column headers (#7463) Github issue / Community forum post (link here to close automatically): --------- Co-authored-by: Marcus --- .../actions/sheet/appendOrUpdate.operation.ts | 36 +++++++++++-------- .../v2/actions/sheet/update.operation.ts | 36 +++++++++++-------- 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/packages/nodes-base/nodes/Google/Sheet/v2/actions/sheet/appendOrUpdate.operation.ts b/packages/nodes-base/nodes/Google/Sheet/v2/actions/sheet/appendOrUpdate.operation.ts index 459bb85e6f..5350f02b53 100644 --- a/packages/nodes-base/nodes/Google/Sheet/v2/actions/sheet/appendOrUpdate.operation.ts +++ b/packages/nodes-base/nodes/Google/Sheet/v2/actions/sheet/appendOrUpdate.operation.ts @@ -280,6 +280,21 @@ export async function execute( const updateData: ISheetUpdateData[] = []; const appendData: IDataObject[] = []; + const errorOnUnexpectedColumn = (key: string, i: number) => { + if (!columnNames.includes(key)) { + throw new NodeOperationError(this.getNode(), 'Unexpected fields in node input', { + itemIndex: i, + description: `The input field '${key}' doesn't match any column in the Sheet. You can ignore this by changing the 'Handling extra data' field, which you can find under 'Options'.`, + }); + } + }; + + const addNewColumn = (key: string) => { + if (!columnNames.includes(key)) { + newColumns.add(key); + } + }; + const mappedValues: IDataObject[] = []; for (let i = 0; i < items.length; i++) { if (dataMode === 'nothing') continue; @@ -292,22 +307,11 @@ export async function execute( data.push(items[i].json); } if (handlingExtraDataOption === 'error') { - Object.keys(items[i].json).forEach((key) => { - if (!columnNames.includes(key)) { - throw new NodeOperationError(this.getNode(), 'Unexpected fields in node input', { - itemIndex: i, - description: `The input field '${key}' doesn't match any column in the Sheet. You can ignore this by changing the 'Handling extra data' field, which you can find under 'Options'.`, - }); - } - }); + Object.keys(items[i].json).forEach((key) => errorOnUnexpectedColumn(key, i)); data.push(items[i].json); } if (handlingExtraDataOption === 'insertInNewColumn') { - Object.keys(items[i].json).forEach((key) => { - if (!columnNames.includes(key)) { - newColumns.add(key); - } - }); + Object.keys(items[i].json).forEach(addNewColumn); data.push(items[i].json); } } else { @@ -324,6 +328,7 @@ export async function execute( "At least one value has to be added under 'Values to Send'", ); } + // eslint-disable-next-line @typescript-eslint/no-loop-func const fields = valuesToSend.reduce((acc, entry) => { if (entry.column === 'newColumn') { const columnName = entry.columnName as string; @@ -358,12 +363,15 @@ export async function execute( } if (newColumns.size) { + const newColumnNames = columnNames.concat([...newColumns]); await sheet.updateRows( sheetName, - [columnNames.concat([...newColumns])], + [newColumnNames], (options.cellFormat as ValueInputOption) || cellFormatDefault(nodeVersion), headerRow + 1, ); + columnNames = newColumnNames; + newColumns.clear(); } const preparedData = await sheet.prepareDataForUpdateOrUpsert( diff --git a/packages/nodes-base/nodes/Google/Sheet/v2/actions/sheet/update.operation.ts b/packages/nodes-base/nodes/Google/Sheet/v2/actions/sheet/update.operation.ts index f851a8a1c0..2f1d4b65fa 100644 --- a/packages/nodes-base/nodes/Google/Sheet/v2/actions/sheet/update.operation.ts +++ b/packages/nodes-base/nodes/Google/Sheet/v2/actions/sheet/update.operation.ts @@ -280,6 +280,21 @@ export async function execute( const mappedValues: IDataObject[] = []; + const errorOnUnexpectedColumn = (key: string, i: number) => { + if (!columnNames.includes(key)) { + throw new NodeOperationError(this.getNode(), 'Unexpected fields in node input', { + itemIndex: i, + description: `The input field '${key}' doesn't match any column in the Sheet. You can ignore this by changing the 'Handling extra data' field, which you can find under 'Options'.`, + }); + } + }; + + const addNewColumn = (key: string) => { + if (!columnNames.includes(key)) { + newColumns.add(key); + } + }; + for (let i = 0; i < items.length; i++) { if (dataMode === 'nothing') continue; @@ -291,22 +306,11 @@ export async function execute( data.push(items[i].json); } if (handlingExtraDataOption === 'error' && columnsToMatchOn[0] !== 'row_number') { - Object.keys(items[i].json).forEach((key) => { - if (!columnNames.includes(key)) { - throw new NodeOperationError(this.getNode(), 'Unexpected fields in node input', { - itemIndex: i, - description: `The input field '${key}' doesn't match any column in the Sheet. You can ignore this by changing the 'Handling extra data' field, which you can find under 'Options'.`, - }); - } - }); + Object.keys(items[i].json).forEach((key) => errorOnUnexpectedColumn(key, i)); data.push(items[i].json); } if (handlingExtraDataOption === 'insertInNewColumn' && columnsToMatchOn[0] !== 'row_number') { - Object.keys(items[i].json).forEach((key) => { - if (!columnNames.includes(key)) { - newColumns.add(key); - } - }); + Object.keys(items[i].json).forEach(addNewColumn); data.push(items[i].json); } } else { @@ -323,6 +327,7 @@ export async function execute( "At least one value has to be added under 'Values to Send'", ); } + // eslint-disable-next-line @typescript-eslint/no-loop-func const fields = valuesToSend.reduce((acc, entry) => { if (entry.column === 'newColumn') { const columnName = entry.columnName as string; @@ -361,12 +366,15 @@ export async function execute( } if (newColumns.size) { + const newColumnNames = columnNames.concat([...newColumns]); await sheet.updateRows( sheetName, - [columnNames.concat([...newColumns])], + [newColumnNames], (options.cellFormat as ValueInputOption) || cellFormatDefault(nodeVersion), headerRow + 1, ); + columnNames = newColumnNames; + newColumns.clear(); } let preparedData;