How do I get specific value from JSON string in Google Script? - api

I'm trying to extract a specific value from this json file:
An example value I'm looking for is exDividendDate, fmt : 2020-09-24.
The code I've written to extract the value doesn't doesn't extract this or any other value and I'm not sure why. Any help would be greatly appreciated.
The error I get in the Google Apps Script is:
TypeError: Cannot read property 'earningsDate' of undefined (line 44,
file "Stock Database"
function callAPI(symbol) {
// Call the API
var url = 'https://query2.finance.yahoo.com/v10/finance/quoteSummary/'
var modules = "?modules=calendarEvents"
var response = UrlFetchApp.fetch(url + symbol + modules);
// Parse the JSON reply
var json = response.getContentText();
var data = JSON.parse(json);
console.log(data)
return JSON.parse(json)
}
function displayFinancials() {
// Load sheets
var dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Results");
var modelSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Financial Ratios Model");
// Get model input data
var company = "Apple"
var symbol = "AAPL"
// call the API
var api = callAPI(symbol);
var results = api[0];
// Output the API result
var output = [company, symbol, results.exDividendDate.fmt]
console.log(output);
dataSheet.appendRow(output)
}

When I saw the JSON data, it seems that exDividendDate is callAPI(symbol).quoteSummary.result[0].calendarEvents. So how about the following modification?
From:
var results = api[0];
To:
var results = api.quoteSummary.result[0].calendarEvents;

Related

Translate an entire page with Google Translate API

I'm using the google Translate API to translate content that's inside an IFRAME. When using the API, I notice that it returns a array(string) with the translated texts, but when inserting it in the DOM, the entire structure disappears, leaving only the text.
The original Page
The result page after the response of the Google API (translate in Portuguese)
This is the code that I'm using:
function translate(lang) {
var iframe = document.getElementById('mainIframe');
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
var iframeBody = iframeDoc.body;
var iframeHTML = iframeDoc.documentElement;
var iframeText = iframeBody.innerText || iframeHTML.innerText;
var url = 'https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=pt&dt=t&q=' + encodeURI(iframeText);
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var response = JSON.parse(xhr.responseText);
var translatedText = ''
for (var i = 0; i < response[0].length; i++) {
translatedText += response[0][i][0];
}
iframeDoc.body.innerHTML = translatedText;
}
};
xhr.send();
}
How can I not affect the structure within the Iframe (Not to be like the second image I sent above)? Just replace the original text with what comes in the response and leave the original look.
I've already tried using functions to find the original text in the DOM to replace it with the translated text but without success. In this case, the idea was just to replace the text correspondence literally.
Thanks for your help and thanks in advance

Suitescript error: TypeError: Cannot set property "JSZipSync" of undefined

I have the following script where I am getting an error message:
org.mozilla.javascript.EcmaError: TypeError: Cannot set property
"JSZipSync" of undefined to
"org.mozilla.javascript.InterpretedFunction#6e57e155"
(/SuiteScripts/Suitelet to Excel.js#17(eval)#2)
According to Netsuite support, there are no issues with the script and they are not getting this error message
/**
*#NApiVersion 2.x
*#NScriptType Suitelet
*/
define(["N/search", "N/file", "N/https"], function (search, file, https) {
function onRequest(context) {
// Load the xlsx library from the CDN
var response = https.get({
url: "https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.0/xlsx.full.min.js",
});
var script = response.body;
eval(script);
// Replace this with the ID of the saved search you want to run
var searchId = "customsearch_my_saved_search";
// Run the search and get the results
var searchResult = search.load({
id: searchId,
});
var searchRows = searchResult.run().getRange({
start: 0,
end: 1000,
});
// Create an array to hold the data for the Excel file
var data = [];
// Add the column names as the first row
var columnNames = [];
searchResult.columns.forEach(function (column) {
columnNames.push(column.label);
});
data.push(columnNames);
// Add the search results to the data array
searchRows.forEach(function (row) {
var rowData = [];
searchResult.columns.forEach(function (column) {
rowData.push(
row.getValue({
name: column.name,
})
);
});
data.push(rowData);
});
// Create the Excel file
var ws = XLSX.utils.aoa_to_sheet(data);
var wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
var binaryData = XLSX.write(wb, {
type: "binary",
bookType: "xlsx",
});
var fileName = "search_results.xlsx";
var folderId = -4; // -4 represents the "Home" folder in the file cabinet
var file = file.create({
name: fileName,
fileType: file.Type.EXCEL,
contents: binaryData,
folder: folderId,
});
// Send the file as a response to the user
context.response.writeFile({
file: file,
isInline: true,
});
});
}
return {
onRequest: onRequest,
};
});
I can't tell where I am going wrong?
The JSZipSync is a function in the xlsx.full.min.js library which I believe I have loaded correctly.
I have also tried storing this file in the filing cabinet and referencing that instead of a link to the CDN website.
The same error message is generated in both cases

How to pull data from Jenkins API to Google Sheet

I want to retrieve data via Jenkins API using Google Sheet Script and store it in Google Sheet
1) Pull Jenkins Job Builds using Jenkins API to Google Sheet - DONE
2) Store data to Google Sheet ???
(need only "builds.subBuilds.buildNumber" and "builds.subBuilds.duration" values)
(need to correct mistake in the script)
function getJenkinsBuilds() {
// get the jenkins job
var response = UrlFetchApp.fetch('http://jenkins.[domain].co/job/Build+Deploy/api/json', {
'method': 'get',
'muteHttpExceptions' : true,
'headers' : {'Authorization' : 'Basic [tokan]'},
});
// parse the json reply and return builds
var data = JSON.parse(response);
var builds = data["builds"];
Logger.log(builds);
return builds;
};
// store predefined parameters from builds in the spreadsheet
function setDataToTable() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Jenkins');
var cell = sheet.getRange("A1");
var rows = [['buildNumber','duration'],['','']]; // I GUESS THE MISTAKE IS HERE?
sheet.getRange(cell.getRow(), cell.getColumn(), rows.length, rows[0].length).setValues(rows);
}
Actual result:
Log shows retrieved array with Builds objects, i.e.:
[19-10-10 16:18:16:937 AEDT] [{number=2081, subBuilds=[{jobName=...
'Jenkins' spreadsheet is empty.
Expected result:
Store "builds.subBuilds.buildNumber" and "builds.subBuilds.duration" values
in the Google Sheet ('Jenkins' spreadsheet), i.e.:
buildNumber duration
123 15sec
456 16sec
... ...
I was able to make it working in the next way:
function getJenkinsBuilds()
{
// get jenkins builds
var response = UrlFetchApp.fetch('http://jenkins.[domain].co/job/Build+Deploy/api/json', {
'method': 'get',
'muteHttpExceptions' : true,
'headers' : {'Authorization' : 'Basic [token]'}
});
// parse the json reply
var data = JSON.parse(response);
var builds = data["builds"];
var number = data['builds'][0]['number'];
var url = data['builds'][0]['url'];
Logger.log(number);
Logger.log(url);
// fill in the spreadsheet with data
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Jenkins');
var cell = sheet.getRange('A1');
var rows = [['BUILD']];
for (var i = 0; i < builds.length; i++)
{
var number = data['builds'][i]['number'];
var url = data['builds'][i]['url'];
rows.push(['=HYPERLINK("'+url+'","'+number+'")']);
Logger.log(number);
Logger.log(url);
sheet.getRange(cell.getRow(), cell.getColumn(), rows.length, rows[0].length).setValues(rows);
}
};

Display dynamic data with JSON API Jquery

I've been reading about Javascript for 2 days now and I'm still confused. I'm familiar with HTML and CSS. My goal is to display a dynamic value on my website. The data will be from an API call using JSON.
The URL i'm using displays info like this
{
"error" : 0,
"error_message" : "-",
"amount" : 35.63000
}
What I want to do is take the "amount" variable and display it on my website. So far I have managed to jumble a bunch of code together that barely makes sense to me. I'm probably using all the wrong syntax so I will continue to try and figure this out myself. All this does it displays a static variable in "div1". What is the best way to convert the variable from the API call to show instead.
$.getJSON('https://www.amdoren.com/api/currency.php?api_key=jbqe5fH8AykJTFbnyR7Hf3d2n3KVQR&from=USD&to=THB&amount=1', function(data) {
//data is the JSON string
});
////
var $items = $('#amount')
var obj = {}
$items.each(function() {
obj[this.id] = $(this).val();
})
var json = JSON.stringify(obj);
///
var obj = [ {
"error": 0,
"error_message": "-",
"amount": 35.60000 ///THIS IS OBVIOUSLY STATIC...
}]
var tbl = $("<table/>").attr("id", "mytable");
$("#div1").append(tbl);
for (var i = 0; i < obj.length; i++) {
var tr = "<tr>";
var td3 = "<td>" + obj[i]["amount"] + "</td></tr>";
$("#mytable").append(tr + td3);
}

How to manage depending functions in nodejs

I am trying to teach myself nodejs and expressjs, however coming from java and c++ this is proving difficult to get used to.
I made a simple and messy module that it is supposed to return a weather forecast for a given zip code.
The way this happens is by taking the user zip code and using a google api to generate the geo coordinates for that zip code. I get the coordinates from the JASON file and then provide them to the next api call, this call is done to the forecast.io api and this time the weather data for the location is also taken from a JASON file.
Coming from java and with a not so solid background on JavaScript I am having a hard time making these two functions wait for one another, in this case I need the google api call to finish first because the coordinates it will provide are needed for the second api call. Can someone take a look at this code and tell me if the strategy I used is correct/ provide a suggestion so that I can know what is done in javascript in situations like this.
here is the code:
// The required modules.
var http = require("http");
var https = require("https");
//result object
var resultSet = {
latitude :"",
longitude:"",
localInfo:"",
weather:"",
humidity:"",
pressure:"",
time:""
};
//print out error messages
function printError(error){
console.error(error.message);
}
//Forecast API required information:
//key for the forecast IO app
var forecast_IO_Key = "this is my key, not publishing for security reasons";
var forecast_IO_Web_Adress = "https://api.forecast.io/forecast/";
//Create Forecast request string function
function createForecastRequest(latitude, longitude){
var request = forecast_IO_Web_Adress + forecast_IO_Key + "/"
+ latitude +"," + longitude;
return request;
}
//Google GEO API required information:
//Create Google Geo Request
var google_GEO_Web_Adress = "https://maps.googleapis.com/maps/api/geocode/json?address=";
function createGoogleGeoMapRequest(zipCode){
var request = google_GEO_Web_Adress+zipCode + "&sensor=false";
return request;
}
function get(zipCode){
// 1- Need to request google for geo locations using a given zip
var googleRequest = https.get(createGoogleGeoMapRequest(zipCode), function(response){
//console.log(createGoogleGeoMapRequest(zipCode));
var body = "";
var status = response.statusCode;
//a- Read the data.
response.on("data", function(chunk){
body+=chunk;
});
//b- Parse the data.
response.on("end", function(){
if(status === 200){
try{
var coordinates = JSON.parse(body);
resultSet.latitude = coordinates.results[0].geometry.location.lat;
resultSet.longitude = coordinates.results[0].geometry.location.lng;
resultSet.localInfo = coordinates.results[0].address_components[0].long_name + ", " +
coordinates.results[0].address_components[1].long_name + ", " +
coordinates.results[0].address_components[2].long_name + ", " +
coordinates.results[0].address_components[3].long_name + ". ";
}catch(error){
printError(error.message);
}finally{
connectToForecastIO(resultSet.latitude,resultSet.longitude);
}
}else{
printError({message: "Error with GEO API"+http.STATUS_CODES[response.statusCode]})
}
});
});
function connectToForecastIO(latitude,longitude){
var forecastRequest = https.get(createForecastRequest(latitude,longitude),function(response){
// console.log(createForecastRequest(latitude,longitude));
var body = "";
var status = response.statusCode;
//read the data
response.on("data", function(chunk){
body+=chunk;
});
//parse the data
response.on("end", function(){
try{
var weatherReport = JSON.parse(body);
resultSet.weather = weatherReport.currently.summary;
resultSet.humidity = weatherReport.currently.humidity;
resultSet.temperature = weatherReport.currently.temperature;
resultSet.pressure = weatherReport.currently.pressure;
resultSet.time = weatherReport.currently.time;
}catch(error){
printError(error.message);
}finally{
return resultSet;
}
});
});
}
}
//define the name of the outer module.
module.exports.get = get;
is the return statement properly placed? Is my use of finally proper in here? Please notice that I come from a java background and in java is perfectly fine to use the try{} catch(){} and finally{} blocks to execute closure code, it was the only way i managed this module to work. But now that i have incorporated some Express and I try to execute this module's method from another module, all I am getting is an undefined return.
You could use the Promise API, kind of like Futures in Java, so basically what you could do is wrap both functions in promises and the you could wait for resolve to execute the next function
var googleRequest = function(zipcode) {
return new Promise(function(resolve, reject) {
var request = https.get(createGoogleGeoMapRequest(zipCode), function(response) {
if (response.statusCode !== 200) {
reject(new Error('Failed to get request status:' + response.statusCode));
}
var body = "";
//a- Read the data.
response.on("data", function(chunk) {
body+=chunk;
});
//b- Parse the data.
response.on("end", function(body) {
var coordinates = JSON.parse(body);
resultSet.latitude = coordinates.results[0].geometry.location.lat;
resultSet.longitude = coordinates.results[0].geometry.location.lng;
resultSet.localInfo = coordinates.results[0].address_components[0].long_name + ", " +
coordinates.results[0].address_components[1].long_name + ", " +
coordinates.results[0].address_components[2].long_name + ", " +
coordinates.results[0].address_components[3].long_name + ". ";
resolve(resultSet);
})
});
request.on('error', function(err) {
reject(err);
});
});
}
After that you could just do
googleRequest(90210).then(function(result) {
connectToForecastIO(result.latitude, result.longitude);
}
You can find out more about Promise's usage in the Promise API docs
You should also note that there are several libraries available that allow for promise based http requests such as fetch