googleapis / googleapis/google-api-nodejs-client

Google Sheets API: Update call duplicates last row when deleting another one

Open
#3,088 0 comments 0 reactions 0 assignees View on GitHub
priority: p2 type: bug
Dominant language
TypeScript
Stars
12.2k
Forks
2k
Avg merge
1d 9h
Merged PRs (30d)
24

Description

Hi,

When trying to bulk update all rows in a spreadsheet, if I delete any row, the last row in the sheet gets duplicated. As if somehow the row count is mandatorily enforced when calling `sheets.spreadsheets.values.update()`.

```js
import { google } from 'googleapis';
import sortBy from 'lodash/sortBy';

const range = 'Sheet1'; // update the whole sheet
let sheets;

export async function handleUpdateSheet({ rowToUpsert }) {
try {
if (!sheets) await initSheets();

const { data: currentData } = await getSheet();

const newValues = upsertOrDeleteRow(currentData, rowToUpsert);

const updated = await updateSheet(newValues);

return updated;
} catch (e) {
return { error: e.message };
}
}

async function initSheets() {
const auth = await google.auth.getClient({ scopes: ['https://www.googleapis.com/auth/spreadsheets'] });
sheets = google.sheets({ version: 'v4', auth });
}

function getSheet() {
return sheets.spreadsheets.values.get({
spreadsheetId: process.env.SHEET_ID,
range,
});
}

function updateSheet(values) {
const request = {
spreadsheetId: process.env.SHEET_ID,
range,
valueInputOption: 'RAW',
resource: { range, majorDimension: 'ROWS', values },
};

return sheets.spreadsheets.values.update(request).then(res => res.data);
}

function upsertOrDeleteRow(currentData, rowToUpsert) {
const headerRows = currentData.values.slice(0, 2);
const valueRows = currentData.values.slice(2);

const rowIndex = valueRows.findIndex(([id]) => id === rowToUpsert.id);

// new item: insert
if (rowIndex === -1) valueRows.push(rowToUpsert);
// existing and active: update
else if (rowToUpsert.active) valueRows[rowIndex] = rowToUpsert;
// existing and inactive: delete
else valueRows.splice(rowIndex, 1);

return headerRows.concat(sortBy(valueRows, ([id]) => id));
}

```

#### Environment details

- OS: MacOS Monterey
- Node.js version: 14.18.3
- yarn version: 1.21.1
- `googleapis` version: 108.0.0

#### Steps to reproduce

1. Load all rows in a spreadsheet by only specifying the sheet name as `range` (with no cells)
2. Remove a row
3. Bulk update

_Expected:_

Deleted row is not present and the row count is decreased by 1.

_Actual:_

The deleted row is removed but the last row is duplicated as if the sheet is forcing the row count.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.