Top level of JSON files, object? array? - json

I am using flutter/dart to fetch JSON files from Google Sheet. I use 2 different methods to get the same Google sheet, one is by scripting and the other is from 'sheetlabs' service. However, sheetlabs works and scripting fails. The top level from sheetlabs is an array while the top level from scripting is an object.
I just copy the scripting file from YouTube and I have no idea of google scripting. How can I modify the scripting code to make the top level being and array just like sheetlabs' file?
The structure of google sheet is relatively simple-- 10 columns with 'stockcode','stockname' ,etc as header which are freezed. Six stocks' data in rows.
Below is the scripting code.
function doGet(e){
var ss = SpreadsheetApp.openByUrl("MY ORIGINAL GOOGLE SHEET'S URL ADDRESS");
var sheet = ss.getSheetByName("sheet1");
return getUsers(sheet);
}
function getUsers(sheet){
var jo = {};
var dataArray = [];
var rows = sheet.getRange(2,1,sheet.getLastRow()-1, sheet.getLastColumn()).getValues();
for(var i = 0, l= rows.length; i<l ; i++){
var dataRow = rows[i];
var record = {};
record['stockname'] = dataRow[0];
record['stockcode'] = dataRow[1];
record['marketvalue'] = dataRow[2];
record['amount'] = dataRow[3];
record['currentprice'] = dataRow[4];
record['averagecost'] = dataRow[5];
record['profit'] = dataRow[6];
record['profitpercent'] = dataRow[7];
record['previousclosingprice'] = dataRow[8];
record['todaysprofit'] = dataRow[9];
dataArray.push(record);
}
jo.user = dataArray;
var result = JSON.stringify(jo);
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}

You create json objects in the for loop.
You need to comment out var jo = {};
The following should work:
function doGet(e){
var ss = SpreadsheetApp.openByUrl("MY ORIGINAL GOOGLE SHEET'S URL ADDRESS");
var sheet = ss.getSheetByName("sheet1");
return getUsers(sheet);
}
function getUsers(sheet){
var dataArray = [];
var rows = sheet.getRange(2,1,sheet.getLastRow()-1, sheet.getLastColumn()).getValues();
for(var i = 0, l= rows.length; i<l ; i++){
var dataRow = rows[i];
var record = {};
record['stockname'] = dataRow[0];
record['stockcode'] = dataRow[1];
record['marketvalue'] = dataRow[2];
record['amount'] = dataRow[3];
record['currentprice'] = dataRow[4];
record['averagecost'] = dataRow[5];
record['profit'] = dataRow[6];
record['profitpercent'] = dataRow[7];
record['previousclosingprice'] = dataRow[8];
record['todaysprofit'] = dataRow[9];
dataArray.push(record);
}
var result = JSON.stringify(dataArray);
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);

Related

Google Apps Script Error "Exception: Invalid argument: options. Should be of type: Map"

I'm trying to make a quick script to copy information from a series of spreadsheets into a single spreadsheet. I'm getting an error
"Exception: Invalid argument: options. Should be of type: Map".
I know very little about maps, and this error makes no sense to me.
function make_new_contact_lists() {
DriveApp.getFileById("1IZBpDno4MOBeiGJeIKd2ykHpCr2359jhcV_SJpSuQ94");
var ss = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSpreadsheet(ss);
var sheet = ss.getSheetByName("Sheet2")
ss.setActiveSheet(sheet);
var lr = sheet.getLastRow();
var range = sheet.getRange("A2:B" + lr).getValues();
var list = [];
list.push([range]);
for (i = 0; i < list.length; i++) {
var entry = list[i];
var name = entry[0];
var fileID = entry[1];
var newsheet =
SpreadsheetApp.openById("1IZBpDno4MOBeiGJeIKd2ykHpCr2359jhcV_SJpSuQ94");
SpreadsheetApp.setActiveSpreadsheet(newsheet);
/**-->This is where the error gets flagged**/
newsheet.insertSheet(name);
var newsheet2 = newsheet.setActiveSheet(name);
var file = SpreadsheetApp.getFileById(fileID);
var spreadsheet = file.setActiveSpreadsheet();
var current = spreadsheet.getSheetByName("Current Contacts");
spreadsheet.setActiveSheet(current);
var range2 = current.getRange("A1:G3").getValues();
current.setValues
}
}
Thank you for any help you can provide
Issue:
var range = sheet.getRange("A2:B"+lr).getValues();//[[a2,b2],..]
var list = [];
list.push([range]); //[[[[a2,b2],[a3,b3],..]]]
for (i=0; i < list.length; i++){
var entry = list[i];//[[[a2,b2],[a3,b3],..]]
var name = entry[0];//[[a2,b2],[a3,b3],..]
list is a 4D array and name is a 2D array. newsheet.insertSheet(name) expects name to be a string or object, whereas the script is providing a 2D array.
Solution:
Directly access range as a 2D array, which makes name a string
Snippet:
const range = sheet.getRange("A2:B"+lr).getValues();//[[a2,b2],..]
for (const i=0; i < range.length; i++){
var entry = range[i];//[a2,b2]
var name = entry[0];//"a2"
Some of your code simply does not make sense. You might be better of to start again with this:
function make_new_contact_lists() {
DriveApp.getFileById("1IZBpDno4MOBeiGJeIKd2ykHpCr2359jhcV_SJpSuQ94");
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet2")
const lr = sh.getLastRow();
const vs = sh.getRange("A2:B" + lr).getValues();
const ss1 = SpreadsheetApp.openById("1IZBpDno4MOBeiGJeIKd2ykHpCr2359jhcV_SJpSuQ94");
for (i = 0; i < vs.length; i++) {
let entry = vs[i];
let name = entry[0];
let fileID = entry[1];
let nsh = ss1.insertSheet(name);
let ss2 = SpreadsheetApp.openById(fileID);
let csh = ss2.getSheetByName("Current Contacts");
let vs2 = csh.getRange("A1:G3").getValues();
//the rest of the code makes no sense
csh.setValues
}
}
And don't just make up methods go read the documentation about them paying attention to parameters and return values.

How to define numbers inside a string to map JSON in Javascript?

The API has numbers to define each of the data containers, I've tried to use several ways to be able to define these numbers, but without success.
In the image you can see the map clubes.262 clubes.264 clubes.265 clubes.266 clubes.275
My attempts:
var idclub = clubes[i].id;
var idclub = clubes.[i].id;
var idclub = clubes[0][i].id;
var idclub = clubes. + i + .id;
The complete script for easy viewing:
function MenuMercadoCartola1() {
var url = 'https://api.cartolafc.globo.com/atletas/mercado';
var response = UrlFetchApp.fetch(url);
var results = JSON.parse(response.getContentText());
var clubes = results.clubes;
var table = [['ID do Clubes','Nome do Clube']];
for (var i = 0; i < clubes.length; i++) {
var idclub = clubes[i].id;
var nameclub = clubes[i].nome;
table.push([idclub,nameclub]);
}
var sheet = SpreadsheetApp.getActive().getSheetByName('Menu');
sheet.getRange(1,1, table.length, table[0].length).setValues(table);
}
It appears that you should be using a 'for in' loop.
Your code revised:
for (var idclub in clubes)
{
idclub = +idclub;
var nameclub = clubes[idclub].nome;
table.push([idclub, nameclub]);
}
Your loop assumes clubes is an array however it is an object which means you could have to iterate on it using a for (var ... in ...) loop.

TypeError: Cannot read property '0' of undefined (Google Sheets / App Script)

I would like to know what I need to adjust in the script so that the results appear in the spreadsheet:
TypeError: Cannot read property '0' of undefined (line 7)
function Cartola() {
var url = "https://api.cartolafc.globo.com/mercado/destaques";
var response = UrlFetchApp.fetch(url);
var data = response.getContentText();
var result = JSON.parse(data);
var apelido = result.Atleta[0].apelido;
var foto = result.Atleta[0].foto;
var clube_nome = result.Atleta[0].clube_nome;
var posição = result.Atleta[0].posicao;
var sheet = SpreadsheetApp.getActiveSheet();
sheet.clear()
var headerRow = ['apelido','foto','clube_nome','posição'];
sheet.appendRow(headerRow);
for(var i=0;i<result[0].Atleta;i++){
var row = [result.Atleta[i].apelido,result.Atleta[i].foto,result.Atleta[i].clube_nome,result.Atleta[i].posicao];
SpreadsheetApp.getActiveSheet().appendRow(row);
}
}
data is an array, so you need to access the element first:
var apelido = result[0].Atleta.apelido;
I think you're trying to print every player to spreadsheet, but what you've written is only looking at one of the players. Please first look at the data returned by the API and understand its structure. Looks something like this:
[
{
"Atleta": {
"atleta_id": 68952,
"nome": "Mário Sérgio Santos Costa",
"apelido": "Marinho",
"foto": "https://s.glbimg.com/es/sde/f/2019/05/30/cd8a7f9b0744e105efa0a0c572d37d6f_FORMATO.png",
"preco_editorial": 5
},
"escalacoes": 996124,
"clube": "SAN",
"clube_nome": "Santos",
"clube_id": 277,
"escudo_clube": "https://s.glbimg.com/es/sde/f/organizacoes/2014/04/14/santos_60x60.png",
"posicao": "Atacante",
"posicao_abreviacao": "ATA"
}
]
Once you understand the data, then consider this modified script, which uses batch operations to run much more quickly.
function Cartola() {
var url = 'https://api.cartolafc.globo.com/mercado/destaques';
var response = UrlFetchApp.fetch(url);
var results = JSON.parse(response.getContentText());
var table = [['apelido','foto','clube_nome','posição']];
for (var i = 0; i < results.length; i++) {
var r = results[i];
var apelido = r.Atleta.apelido;
var foto = r.Atleta.foto;
var clube_nome = r.clube_nome;
var posição = r.posicao;
table.push([apelido, foto, clube_nome, posição]);
}
var sheet = SpreadsheetApp.getActiveSheet();
sheet.clear().getRange(1, 1, table.length, table[0].length).setValues(table);
}

Parse JSON formatted result of HTTP request into columns

Google Apps Script to pull data from API. I'd like to parse out the information according to the relevant headers.
function Fraud2() {
var ret = "no value";
var response = UrlFetchApp.fetch("https://fraudshield.24metrics.com/api/v1/reports/fraud.json?tracker_id=905&group[]=sub_id&group[]=partner&date_start=2018-01-18&date_end=2018-01-18&timezone=UTC&user_id=XXX&api_token=XXX",{muteHttpExceptions:true})
var user_id = "XXX";
var api_token = "XXX";
var sheet = SpreadsheetApp.getActiveSheet();
sheet.appendRow([response]);
}
The return is pushed into one single cell like so:
{"results":[{"tracker_id":905,"conversion":7883,"click":0,"goal":0,"approved":6511,"rejected":1372,"tracker":"Tatoo
Integration","conversion_rate":"N\/A"},{"tracker_id":906,"conversion":1868,"click":0,"goal":0,"approved":1682,"rejected":186,"tracker":"Aise
Integration","conversion_rate":"N\/A"},{"tracker_id":933,"conversion":413,"click":0,"goal":0,"rejected":290,"approved":123,"tracker":"Tatoo
Invalids Integration","conversion_rate":"N\/A"}]}
I tried this without success.
How can I get the results arranged neatly into columns?
As Hink said, you need to convert the object to an array first.
Hinks solution will work fine but below is a combination of the code you tried to use in your post.
function Fraud2() {
var ss = SpreadsheetApp.getActiveSheet();
var ret = "no value";
var response = UrlFetchApp.fetch("https://fraudshield.24metrics.com/api/v1/reports/fraud.json?tracker_id=905&group[]=sub_id&group[]=partner&date_start=2018-01-18&date_end=2018-01-18&timezone=UTC&user_id=XXX&api_token=XXX",{muteHttpExceptions:true})
var user_id = "XXX";
var api_token = "XXX";
var out=JSON.stringify(response.results);
out=JSON.parse(out)
var title = [];
for (var i in out[0]) {
title.push(i);
}
var res = [];
res.push(title);
for (var i in out) {
var values = [];
for (var j in out[i]) {
values.push(out[i][j]);
}
res.push(values);
}
ss.getRange(1, 1, res.length, res[0].length).setValues(res);
};
You need to convert the response object into an array and append the array:
for (var i = 0; i < response.results.length; i++){
var current = response.results[i];
var myArray = [current.tracker_id, current.conversion, current.click, current.goal, current.approved, current.rejected, current.tracker,current.conversion_rate];
sheet.appendRow(myArray);
}

Google Script to use a cell array and return a list of value from Json API

I want to use a list of cell on the same column to build a custom url and fetch API data. I wrote the code for a single cell (and single value return) but don't know how to extend to the entire column:
function checkAddress() {
var addresses = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Addresses");
var baseUrl = 'https://my.api.website/xxxxx&address=';
var address = addresses.getRange(1, 1);
var addrID = address.getValue();
var url = baseUrl.concat(addrID);
var responseAPI = UrlFetchApp.fetch(url);
var json = JSON.parse(responseAPI.getContentText());
var data = [[json.result]];
var dataRange = addresses.getRange(1, 2, 1, 1);
dataRange.setValue(data);
}
The var addrID is the one that change, and all of them are in the A column; I would like to return the result to the B column on the same row.
Any help would be appreciated, thank you
You just need to loop through Col A. Try the below Code.
function checkAddress() {
var addresses = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Addresses");
var baseUrl = 'https://my.api.website/xxxxx&address=';
var data = addresses.getRange(1, 1,addresses.getLastRow()).getValues();
for(var i=0;i<data.length;i++){
var addrID = data[i][0];
var url = baseUrl.concat(addrID);
var responseAPI = UrlFetchApp.fetch(url);
var json = JSON.parse(responseAPI.getContentText());
var data1 = [[json.result]];
var dataRange = addresses.getRange(i+1,2,1).setValue(data1);
}
}