AppScript API returning empty JSON object - javascript

So, I'm trying to build an API using my Google Sheet and I've run into a problem.
Here's my code
function doGet() {
let doc = SpreadsheetApp.getActiveSpreadsheet();
let sheet = doc.getSheetByName('portfolios');
let values = sheet.getDataRange().getValues();
let output = [];
for (let i = 2; i < values.length; i++) {
let row = [];
row['name'] = values[i][0];
row['committee'] = values[i][1];
row['post'] = values[i][2];
//console.log(row)
output.push(row);
}
console.log(output)
return ContentService.createTextOutput(JSON.stringify(output)).setMimeType(ContentService.MimeType.JSON);
}
When I run the script, I get the desired output in the console but when I deploy the API (I've set "Who has access" to Everyone) and send a GET request, I receive an empty JSON object.
[[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]
What am I doing wrong?

On behalf of OP, Himanshu Sardana
I was able to fix the error, turns out it was due to me using the JSON.stringify function incorrectly. I was able to fix it by changing:
let row = [];
to
let row = {};
Edited code:
function doGet() {
let doc = SpreadsheetApp.getActiveSpreadsheet();
let sheet = doc.getSheetByName('portfolios');
let values = sheet.getDataRange().getValues();
let output = [];
for (let i = 2; i < values.length; i++) {
let row = {}; // Edit in question
row['name'] = values[i][0];
row['committee'] = values[i][1];
row['post'] = values[i][2];
//console.log(row)
output.push(row);
}
console.log(output)
return ContentService.createTextOutput(JSON.stringify(output)).setMimeType(ContentService.MimeType.JSON);
}

Related

How to compare an item in an array to all items in other array and add it into shpreadsheet?

I'm developing a tool and currently I'm stuck with a problem.
I'm writing a code in GoogleAppScript (JavaScript) and I have two columns where I collect data. As a result I've two arrays. Let's call them mainArray and checkArray
I need a code doing this logic:
getting the 1st value of the mainArray, i.e. mainArray[0]
chenking the value if it's equal to checkArray[0], then checkArray[1]... checkArray[i]
if there's a match, then toss it to the garbage bin, and swith to the mainArray[1]
Checking mainArray[1] with all of the values from checkArray, as we did it in p.2
If there's no match with any vals from the checkArray add these value into the 3rd array (finArray)
I've done exaclty the opposite.
for (var j=0; j<checkArr.length; j++) {
for(var i=0; i<mainArr.length; i++) {
if(mainArr[i][0]!==''){
if(checkArr[j][0]==mainArr[i][0])
{
Logger.log('not in the list'+mainArr[i][0])
finArr.push(mainArr[i][0])
break;
}}
But I don't know how to get the code working as I described above.
`
// The Arrays actually are one dimensional
// I prefer to create a one dimensional array
// GetDataArray function creates one dimensional array
function GetDataArray(sht,rng) {
var Data = [] var i = 0;
Logger.log(' Sht Name %s\n rng %s,', sht.getName(), rng)
sht.getRange(rng).getValues() .forEach(
function (row) {
row.forEach( function (cell) {
//Logger.log(cell);
Data[i++] = cell }); } );
return Data
} //
......
var sht = SpreadsheetApp.getActiveSheet()
var rngMain = ....// Provide the range
var rngCheck = ...
var checkArr = GetDataArray(sht, rngCheck)
var mainArr = GetDataArray(sht, rngMain)
var finArr = []
mainArr.forEach( function(cell) {
if (cell == '') continue
if (checkArr.indexOf(cell) != -1) finArr.push(cell)})
function thefunc() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet1');
let vs1 = sh.getRange(1,1,sh.getLastRow(),1).getValues().flat();
let vs2 = sh.getRange(1,2,sh.getLastRow(),1).getValues().flat();
let d = 0;
vs1.forEach((r,i) => {
if(~vs2.indexOf(r[0])) {
sh.deleteRow(i+1-d++);//delete row
}
});
}

Javascript - Help retrieving data from Firebase

I have this code below to retrive data from firebase and turn into an array but whenever i call it it stops other functions from being called inside the code even tho I can perfectly call them in the console.
I've worked around this by using callback functions but I am at a point it just doesn't do anymore. How can make this part act like a normal function where I can call anytime without stopping the code.
function genList(){
dataRef.on('value', data => {
let arr = (data.val());
let keys = Object.keys(arr);
for (let i = 0; i < keys.length; i++) {
let k = keys[i];
let title = arr[k].title;
let author = arr[k].author;
let pages = arr[k].pages;
let date = arr[k].date;
let bookmark = arr[k].bookmark;
let newList = new Object();
newList.title = title;
newList.author = author;
newList.pages = pages;
newList.date = date;
newList.bookmark = bookmark;
bookList.push(newList);
}
})}

Why is Data Null?

I came across an error today, and I am not sure why it occurred. At the second for loop, the access to data will be undefined instead of the data that was inserted as a parameter into the function. Somehow the data gets the value of null, instead of the Object that was passed to this function. Does anyone know why? The error I get is "data is not defined".
createDataObject: function (data) {
let dataObj = data.source[0];
let backedData = data.backedData;
for (let i in dataObj) {
let d = dataObj[i];
d.data = { source: d.data };
}
for (let i = 0; i < data.backedData.length; i++) {
let bd = data.backedData[i]; //<- this is where the error occurrs
let data = bd.data[0];
}
}
Here is some code outside of the object, if you want to try, that I was using, this will work on your console or in node. Seems like I have come across a Javascript compiler bug. I am not sure.
createDataObject({source: [[{data: 1}]], backedData: [1,2,3, 4]});
The code above will work if I do the following
createDataObject: function (data) {
let dataObj = data.source[0];
let backedData = data.backedData; //create the backedData variable here
for (let i in dataObj) {
let d = dataObj[i];
d.data = { source: d.data };
}
for (let i = 0; i < backedData.length; i++) {
let bd = backedData[i]; // no Error
let data = bd.data[0];
//.....
}
}
in the second for loop you create another data object. Data is not created on the first line in the for loop.
Try using
for (let i = 0; i < data.backedData.length; i++) {
let bd = data.backedData[i];
let d= bd.data[0]; // Convert data to d or another variable name
//.....
}

Javascript loop through an array of objects and return the first value

I have created a function that is supposed to loop through an array of objects and return the first value of each object.
function getSheetSectionData(name){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(name);
var sheetData = sheet.getDataRange().getValues();
var data = [];
for (var i = 0; i < sheetData.length; i++){
var obj = {};
obj = sheetData[i][0];
return sheetData[i][0];
}
data.push(obj);
}
It's only returning the first item in the first row/column. Any clues on what I'm missing?
You could use Object.keys together with Array#map to get just the first key value from each object.
data = sheetData.map(v => v[Object.keys(v)[0]]);
Working example:
var arr = [{foo: 'bar', bar: 'foo'},{foo: 'war', bar: 'foo'},{foo: 'mar', bar: 'foo'}],
res = arr.map(v => v[Object.keys(v)[0]]);
console.log(res);
How about this solution. Hope it helps!
var sheetData = [{name : "Mike", id: 10},{name : "Laura", id: 23},{name : "carl", id: 25},{name : "Lori", id: 23}];
var arr = []
for(var i in sheetData){
var someObject = sheetData[i];
arr.push(someObject[Object.keys(someObject)[0]]);
}
console.log(arr);
You have to move the return statement outside the loop.
function getSheetSectionData(name){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(name),
sheetData = sheet.getDataRange().getValues(),
data = [];
for (var i = 0; i < sheetData.length; i++){
var obj = {};
obj = sheetData[i][0];
data.push(obj);
}
return data;
}
I'm not sure what your intent is, but probably it should be something like this?
function getSheetSectionData(name){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(name);
var sheetData = sheet.getDataRange().getValues();
var data = [];
for (var i = 0; i < sheetData.length; i++){
var obj = {};
obj = sheetData[i][0];
data.push(obj);
}
return data;
}
UPDATE
As #grogx noted below, creation of a temporary object appears unnecessary in this context and the sample above could be optimized to
function getSheetSectionData(name){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(name);
var sheetData = sheet.getDataRange().getValues();
var data = [];
for (var i = 0; i < sheetData.length; i++){
data.push(sheetData[i][0]);
}
return data;
}
Which can further be shortened to
function getSheetSectionData(name){
return SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName(name)
.getDataRange()
.getValues()
.map((e) => e[0]);
}
However, we do not really know, what the original intent of the OP was. It may be the case, that that temporary object was indeed required for some sort of intermediate transformation, which was striped out from the MCVE.

How to copy specific rows from 3 google spreadsheet to another spreadsheet using google apps script

I have a spreadsheet named Main-spreadsheet ,within them are 4 spreadsheets named sheet1,sheet2,sheet3 & result. I want to copy conditional data from sheet1,sheet2,sheet3 to result sheet.Can anyone pls help me????
This is my code:
var ss = SpreadsheetApp.openById(DATA_SPREADSHEET_ID);
var sheet = ss.getSheets()[3];
var dataSs = SpreadsheetApp.openById(DATA_SPREADSHEET_ID);
var dataSheet = dataSs.getSheets()[0];
// Fetch all the data
var data = getRowsData(dataSheet);
// This is the data we want to display
var columnNames = ["Name", "AC link", "Type"];
// Index data by type
var dataBytype = {};
var types = [];
for (var i = 0; i < data.length; ++i) {
var rowData = data[i];
if (!dataBytype[rowData.type]) {
dataBytype[rowData.type] = [];
types.push(rowData.type);
}
dataBytype[rowData.type].push(rowData);
}
types.sort();
var headerBackgroundColor = dataSheet.getRange(1, 1).getBackgroundColor();
for (var i = 0; i < types.length; ++i) {
var sheet = ss.getSheetByName(types[i]) ||
ss.insertSheet(types[i], ss.getSheets().length);
sheet.clear();
var headersRange = sheet.getRange(1, 1, 1, columnNames.length);
headersRange.setValues([columnNames]);
headersRange.setBackgroundColor(headerBackgroundColor);
setRowsData(sheet, dataBytype[types[i]]);
}
}
it currently copy data fom sheet1 and makes a new sheet by type column
There has been dozens of similar questions and answers on this forum and on the old one... a quick search will help you to find what you're looking for.

Categories

Resources