Public
Edited
Feb 22
1 fork
Importers
6 stars
Insert cell
Insert cell
Insert cell
spreadsheet = async (spreadsheetId) => {
return {
getRange: (range) => getRange(range, spreadsheetId),
updateRange: (range, values) => updateRange(range, values, spreadsheetId)
};
}
Insert cell
spreadsheetView = spreadsheetId => {
const value = spreadsheet(spreadsheetId);
const element = md`https://docs.google.com/spreadsheets/d/${spreadsheetId}`;
element.value = value;
return element;
}
Insert cell
getRange = async (range, spreadsheetId) => {
try {
if (Array.isArray(range)) {
const { result } = await client.sheets.spreadsheets.values.batchGet({
spreadsheetId,
ranges: range,
valueRenderOption
});
return result.valueRanges.reduce(
(result, { range, values }) => ({
...result,
[range]: rangeToObject(values)
}),
{}
);
}
const { result } = await client.sheets.spreadsheets.values.get({
spreadsheetId,
range,
valueRenderOption
});
return rangeToObject(result.values);
} catch (error) {
console.error(error.result.error);
return new Error(error.result.error.message);
}
}
Insert cell
updateRange = async (range, _values, spreadsheetId) => {
try {
const values = objectToRange(_values);
const { result } = await client.sheets.spreadsheets.values.update({
spreadsheetId,
range,
valueInputOption,
responseValueRenderOption,
resource: { values }
});
} catch (error) {
console.error(error.result.error);
return new Error(error.result.error.message);
}
}
Insert cell
Insert cell
Insert cell
valueRenderOption = "FORMATTED_VALUE"
Insert cell
responseValueRenderOption = "FORMATTED_VALUE"
Insert cell
Insert cell
valueInputOption = "USER_ENTERED"
Insert cell
Insert cell
gapi = new Promise((resolve, reject) => {})
Insert cell
client = {
await gapi.client.load(
"https://sheets.googleapis.com/$discovery/rest?version=v4"
);
return gapi.client;
}
Insert cell
rangeToObject = (range) => {
const columns = range[0];
return range.slice(1).map((row) =>
columns.reduce((result, column, index) => {
let value = row[index] || null;
if (value === "TRUE") {
value = true;
}
if (value === "FALSE") {
value = false;
}
return { ...result, [column]: value };
}, {})
);
}
Insert cell
rangeToMap = (range) => {
const columns = range[0];
return range.slice(1).map((row) =>
columns.reduce((result, column, index) => {
let value = row[index] || null;
if (value === "TRUE") {
value = true;
}
if (value === "FALSE") {
value = false;
}
result.set(column, value);
return result;
}, new Map())
);
}
Insert cell
objectToRange = (data) => {
const columns = Object.keys(data[0]);
return [
columns,
...data.map((row) => {
const values = columns.map((column) => {
const value = row[column];
if (!value) {
return "";
}
if (Array.isArray(value)) {
return value.join(",");
}
if (typeof value == "boolean" && value === true) {
return "TRUE";
}
if (typeof value == "boolean" && value === false) {
return "FALSE";
}
if (value instanceof Date) {
return value.toISOString().replace(/T.+/, "");
}
if (typeof value === "object") {
return JSON.stringify(value);
}
return value;
});
return values;
})
];
}
Insert cell
mapToRange = (data) => {
const columns = [...data[0].keys()];
return [
columns,
...data.map((row) => {
const values = columns.map((column) => {
const value = row.get(column);
if (!value) {
return "";
}
if (Array.isArray(value)) {
return value.join(",");
}
if (typeof value == "boolean" && value === true) {
return "TRUE";
}
if (typeof value == "boolean" && value === false) {
return "FALSE";
}
if (typeof value === "object") {
return JSON.stringify(value);
}
return value;
});
return values;
})
];
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more