Get keys of json and use to print values in nodejs - json

I trying to get all keys and use them to access values of that keys, depends of user...
i have this code:
var fs = require('fs');
var _ = require('underscore');
var obj = JSON.parse(fs.readFileSync('ENG.json', 'utf8'));
var lang = process.argv.slice(2);
var keys = _.keys(obj);
console.log(obj.keys[0].text1);
Help me please.

You mean this way?
keys.forEach(key => {
console.log(obj[key]);
});
By the way, no need for underscore. Use Object.keys(obj).
And you can easily require your json this way:
// most probably './ENG.json';
const obj = require('ENG.json');

Related

Google Script - Take on array several cell values at same time

I've developed a script, but it is TOOOOO slow (>1min). I've read that less calls to take values reduces that time, so I'd ask how to do that. The idea is to take the cell values on just one single line, and then for each "let", take one part of that array.
Do you know how to do that? The code is this:
function createPDF() {
const currentSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("CRM");
let profe_nombre = currentSheet.getRange(14,40).getValues();
let profe_direccion = currentSheet.getRange(16,40).getValues();
let profe_dni = currentSheet.getRange(15,40).getValues();
let profe_iban = currentSheet.getRange(17,40).getValues();
let profe_paypal = currentSheet.getRange(18,40).getValues();
let profe_email = currentSheet.getRange(19,40).getValues();
let factura_nombre = currentSheet.getRange(26,39).getValues();
let factura_fecha = currentSheet.getRange(23,40).getDisplayValues();
let factura_importe = currentSheet.getRange(22,40).getValues();
let factura_notas = currentSheet.getRange(26,38).getValues();
const docFile = DriveApp.getFileById("sheetID");
const tempFolder = DriveApp.getFolderById("folderID");
const pdfFolder = DriveApp.getFolderById("folderID");
const tempFile = docFile.makeCopy(tempFolder);
const tempDocFile = DocumentApp.openById(tempFile.getId());
const body = tempDocFile.getBody()
body.replaceText("{profe_nombre}", profe_nombre);
body.replaceText("{profe_direccion}", profe_direccion);
body.replaceText("{profe_dni}", profe_dni);
body.replaceText("{profe_iban}", profe_iban);
body.replaceText("{profe_paypal}", profe_paypal);
body.replaceText("{profe_email}", profe_email);
body.replaceText("{factura_nombre}", factura_nombre);
body.replaceText("{factura_fecha}", factura_fecha);
body.replaceText("{factura_importe}", factura_importe);
body.replaceText("{factura_notas}", factura_notas);
tempDocFile.saveAndClose();
const pdfContentBlob = tempFile.getAs(MimeType.PDF);
pdfFolder.createFile(pdfContentBlob).setName(factura_nombre + ".pdf");
tempFolder.removeFile(tempFile);
SpreadsheetApp.getUi().alert("Factura creada");
}
function apendiceRemesa() {
const SheetCRM = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("CRM");
const SheetRemesas = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Remesas");
let remesa_cuenta = SheetCRM.getRange(17,40).getValue();
let remesa_importe = SheetCRM.getRange(22,40).getValue();
let remesa_nombre = SheetCRM.getRange(14,40).getValue();
let remesa_concepto = SheetCRM.getRange(26,39).getValue();
const remesa_estado_pago = SheetCRM.getRange(24,40).getValue();
let remesa_estado_pago_fila = SheetCRM.getRange(23,43).getValue();
let remesa_estado_pago_columna = SheetCRM.getRange(24,43).getValue();
if (remesa_estado_pago == 'P') {
SheetRemesas.appendRow([remesa_cuenta,remesa_importe,remesa_nombre,remesa_concepto]);
SpreadsheetApp.getActiveSheet().getRange(remesa_estado_pago_fila, remesa_estado_pago_columna).setValue('RM');
} else {
SpreadsheetApp.getUi().alert('ERROR. Esta factura ya fue pagada')
}
}
I've separated both functions because I have two different buttons for each, so it is not mandatory to first execute createPDF and then apendiceRemesa (I will develop a new function too for both functions, removing some redundant variables then).
Thank you!
%%% UPDATE %%%
Yuri and Iamblichus sokution have reduced about 20% of the execution time. Now, I wonder if there is any other way to identify the worksheet name:
From
const currentSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("CRM");
const data = currentSheet.getRange('al8:ar26').getDisplayValues();
To something like this:
const data = getRange("CRM!AL8:AR26").getDisplayValues();
Solution:
First, retrieve a range containing all your desired values. A simple option would be to use getDataRange(), which will simply get a range corresponding to all sheet values.
Then, retrieve the different desired values from the resulting 2D array, using the corresponding indexes (first row index, then column index). It's important to note that arrays are 0-indexed, contrasting with the 1-indexed parameters from getRange, so you'll have to subtract 1 to each index.
Sample:
To show you how it's done, here's a sample that retrieves the first variables:
const values = currentSheet.getDataRange().getDisplayValues();
const profe_nombre = values[13][39];
const profe_direccion = values[15][39];
const profe_dni = values[14][39];
// ...and so on...
Note: If the cells were more contiguous with each other, I would recommend array destructuring to accomplish this with fewer lines of code.
The trick is to get all data from the sheet as a 2d array and then get 'cells' from the array, not directly from the sheet.
Instead of this:
let profe_nombre = currentSheet.getRange(14,40).getValues();
let profe_direccion = currentSheet.getRange(16,40).getValues();
let profe_dni = currentSheet.getRange(15,40).getValues();
let profe_iban = currentSheet.getRange(17,40).getValues();
let profe_paypal = currentSheet.getRange(18,40).getValues();
let profe_email = currentSheet.getRange(19,40).getValues();
let factura_nombre = currentSheet.getRange(26,39).getValues();
let factura_fecha = currentSheet.getRange(23,40).getDisplayValues();
let factura_importe = currentSheet.getRange(22,40).getValues();
let factura_notas = currentSheet.getRange(26,38).getValues();
Try this:
const data = currentSheet.getDataRange().getDisplayValues(); // the 2d array
// take values from the array
let profe_nombre = data[13][39];
let profe_direccion = data[15][39];
let profe_dni = data[14][39];
let profe_iban = data[16][39];
let profe_paypal = data[17][39];
let profe_email = data[18][39];
let factura_nombre = data[25][38];
let factura_fecha = data[22][39];
let factura_importe = data[21][39];
let factura_notas = data[23][37];
Etc.
For your second function apendiceRemesa():
const data = SheetCRM.getDataRange().getValues();
let remesa_cuenta = data[16][39];
let remesa_importe = data[21][39];
let remesa_nombre = data[13][39];
let remesa_concepto = data[25][38];
const remesa_estado_pago = data[23][39];
let remesa_estado_pago_fila = data[22][42];
let remesa_estado_pago_columna = data[23][42];

Get company name in google sheets using stock ticker

I have a google sheet getting stock information by symbol. I found this code below to get prices but don't really understand how it's working.
function yahooF(ticker) {
const url = `https://finance.yahoo.com/quote/${ticker}?p=${ticker}`;
const res = UrlFetchApp.fetch(url, {muteHttpExceptions: true});
const contentText = res.getContentText();
const price = contentText.match(/<fin-streamer(?:.*?)data-test="qsp-price"(?:.*)>(\d+\.\d+)<\/fin-streamer>/);
console.log(price[1]);
return price[1];
}
Does anyone know a way using a similar method to get specifically the company name, but understanding how to use this to get other data would be great. I'm not interested in using =GOOGLEFINANCE functions as they seem to fail pretty often.
Try, by parsing the json inside the source
function yahooFNameOfCompany(ticker) {
const url = `https://finance.yahoo.com/quote/${ticker}?p=${ticker}`;
const res = UrlFetchApp.fetch(url, {muteHttpExceptions: true}).getContentText();
var jsonString = res.match(/(?<=root.App.main = ).*(?=}}}})/g) + '}}}}'
var data = JSON.parse(jsonString)
console.log(data.context.dispatcher.stores.StreamDataStore.quoteData[ticker].shortName)
}

JSON import - Cannot read property 'length' of undefined

I'm trying to import JSON via API into Google sheets but get the error
Cannot read property 'length' of undefined
Here is my code
function importRank(){
url = 'https://public-api.solscan.io/token/holders?tokenAddress=sinjBMHhAuvywW3o87uXHswuRXb3c7TfqgAdocedtDj&offset=0&limit=max'
var json = JSON.parse(UrlFetchApp.fetch(url).getContentText())
var data = json.data.owner
var data2 = json.data.rank
var data3 = json.data.total
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('WalletRank')
sh.getRange(2,1,data.length,data[0].length).setValues(data)
sh.getRange(2,2,data2.length,data2[0].length).setValues(data2)
sh.getRange(2,3,data3.length,data3[0].length).setValues(data3)
}
Try
function importRank(){
url = 'https://public-api.solscan.io/token/holders?tokenAddress=sinjBMHhAuvywW3o87uXHswuRXb3c7TfqgAdocedtDj&offset=0&limit=max'
var json = JSON.parse(UrlFetchApp.fetch(url).getContentText())
var data=[]
Logger.log(json.total)
json.data.forEach(function(x){
data.push([x.owner,x.rank,x.amount])
})
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('WalletRank')
sh.getRange(2,1,data.length,data[0].length).setValues(data)
sh.getRange(2,4).setValue(json.total)
}
Explanation
the structure is as follows
{"data":[
{"address":"__________","amount":________,"decimals":__,"owner":"___","rank":_},
...
],"total":_____}
that means that data is an array [] of multi elements which contains each of them {} address, amount, decimals, owner and rank
Reference
forEach

Access JSON position in Node.js

I have a JSON string in this format:
[
{
"Origin":{
"FtpHost":"info",
"FtpFolder":"info",
"FtpUser":"info",
"FtpPassword":"info",
"FtpInsideFolder":"info",
"Pattern":"info"
},
"Destination":{
"FtpHost":"info",
"FtpFolder":"info",
"FtpUser":"info",
"FtpPassword":"info",
"FtpInsideFolder":"info"
},
"CustomFolderName":"Conad",
"OperationTraverseType":"RootOnly"
}
]
To pick up the JSON I wrote this in Node.js:
var fs = require('fs');
var obj = fs.readFileSync('Operations.json', 'utf8');
I'm wondering, how I can access for example : "Destination" fields?
You must parse this to JSON. because fs.readFile returns string
var fs = require('fs');
var obj = fs.readFileSync('Operations.json', 'utf8');
obj = JSON.parse(obj)
var Destination = obj[0].Destination
// or
var Destination = obj[0]["Destination"]
Edit (as said Diego)
You can also directly require json file
var obj = require('somejsonfile.json');
var Destination = obj[0]. Destination
Just need to simply parse the read data. Something like this:
var fs = require('fs');
var obj = fs.readFileSync('Operations.json', 'utf8').toString();
obj = JSON.parse(obj)
console.log(obj[0].Destination)
you can do like var myjson = JSON.parse(obj) or obj = JSON.parse(fs.readFileSync('Operations.json', 'utf8')) and then access it like obj[0]["Destination"]["FIELD"] where FIELD - represents the "Destination" object field you want

Uncaught SyntaxError, Unexpected Identifier in for loop in jade

I am trying to render a jade with some dynamic content. I am reading from a json in jade.
My json looks like this
{ data1: 'data1',
data2: 'data2',
data3:
[ { name: 'ABC',
address: 'India'
},
{ name: 'DEF',
address: 'Australia'
}]}
I am trying to render a jade and use the data from above json
my jade looks like
var data1 = #{data1};
var data2 = #{data2};
var size = #{data3.length};
for data in #{data3}
var name = data.name;
var address = data.address;
I am able to correctly extract data in the first 3 lines mentioned above. But when I try to fetch data from within a loop, I get "Uncaught SyntaXError, Unexpected Identifier" error while debugging.
If i put a line outisde the for loop, it works fine. Ex
var name = #{data3[0].name};
is rendered properly. But i need to iterate over a loop and fetch data over there. Can somebody help.
Thanks
Updating with more information
1. I have node server running where I create a json -
var json_string = "{"data1":"data1","data2":"data2","data3":[{"name":"ABC","address":"India"},{"name":"DEF","address":"Australia"}]};";
var json_data = JSON.parse(json_string);
console.log(json_data);
res.render('sample_example', json_data);
In my sample_example.jade I have the following snippet within script
var data1 = #{data1};
var data2 = #{data2};
var size = #{data3.length};
for data in #{data3}
var name = data.name;
var address = data.address;
As stated earlier, I am able to properly extract #{data1}, #{data2}, #{data3.length} to the variables . But it breaks within the for loop. In fact, I am able to extract #{data3[0].name} from outside the for loop. But within the for looop it gives the stated error.
This is how you can do it now.
In your server-side you have to JSON.stringify the array of objects.
var json_data = JSON.parse(json_string);
// Convert back to json only the property data3
json_data.data3 = JSON.stringify(json_data.data3);
res.render('simple', json_data);
Or the better is to not parse the JSON just let it go the way it is:
// var json_data = JSON.parse(json_string);
res.render('simple', {
json_data: json_string
});
And in the Jade Template (If you followed the better method):
script(type='text/javascript').
var json_data = !{json_data};
var data1 = json_data.data1;
var data2 = json_data.data2;
var data3 = json_data.data3;
var size = data3.length;
data3.forEach(function(data) {
var name = data.name;
var address = data.address;
console.log(name, address);
});
Also you need to change the loop structure. The for..in used to iterate over objects not array of objects.
This works for me;
- var cdata = {"data1":"data1","data2":"data2","data3":[{"name":"ABC","address":"India"},{"name":"DEF","address":"Australia"}]};
each data in cdata.data3
- var name = data.name;
- var address = data.address;
p Name: #{name}
p Address: #{address}
Can you share the actual jade file contents if updating the code as shown above doesn't work. Also what version of jade and express?