So I'm trying to parse this https://www.quandl.com/api/v3/datasets/CHRIS/CME_GC1 and in my code, show nothing but the last price([4] in data). However, not exactly sure how to do it. So far I have this following code
And that's where I'm stuck.
let goldData = new XMLHttpRequest();
goldData.open('GET', 'https://www.quandl.com/api/v3/datasets/CHRIS/CME_GC1', true);
goldData.send();
goldData.onload = function (response) {
let goldResponse = JSON.parse(this.response);
}
Here you go!
let goldData = new XMLHttpRequest();
goldData.open('GET', 'https://www.quandl.com/api/v3/datasets/CHRIS/CME_GC1', true);
goldData.onload = function() {
var lastPrices = [];
var response = JSON.parse(this.responseText);
var data = response.dataset.data; // get data object from nested object.
// iterate through the data maps to retrieve all the prices.
var dataLength = data.length;
for (var i=0; i<dataLength; i++) {
var d = data[i];
lastPrices.push(d[4]);
}
console.log('lastPrices:', lastPrices);
// last prices from newest to oldest.
}
goldData.send();
Related
This question already has an answer here:
How to create a hyperlink in Google Sheets
(1 answer)
Closed 2 months ago.
I'm using the Discogs API to export my Wantlist to Google Sheets
Is there a way to add the HTML to make the release-url (resource_url) clickable in the output?
function logTheData (url){
var sheet = SpreadsheetApp.getActiveSheet();
var url ='https://api.discogs.com/users/bartvanbelle/wants?per_page=100';
var response = UrlFetchApp.fetch(url); // get feed
var json = response.getContentText(); //
var data = JSON.parse(response);
var counter = 100;
for (var i = 0; i< counter; i++) {
var stats = [];
// var instance_id = data.wants[i].instance_id;
//if (typeof data.wants[i].basic_information.formats[0].descriptions[0] !== "undefined"){
// var description = data.wants[i].basic_information.formats[0].descriptions[0]
// };
// stats.push(instance_id);//works a
stats.push(data.wants[i].basic_information.title); //works a
stats.push(data.wants[i].basic_information.formats[0].name);
// stats.push(description); //stringify array?
stats.push(String(data.wants[i].basic_information.formats[0].descriptions));
stats.push(data.wants[i].basic_information.labels[0].name); //works c
stats.push(data.wants[i].basic_information.labels[0].catno); // work d
stats.push(data.wants[i].basic_information.year); //l
stats.push(data.wants[i].basic_information.artists[0].name); //works j
stats.push(data.wants[i].basic_information.id); // m
stats.push(data.wants[i].basic_information.resource_url); // m
Logger.log(stats);
SpreadsheetApp.getActiveSpreadsheet().appendRow(stats);
}
var pages = data.pagination.pages;
for (var a = 1; a < pages; a++){
var next = data.pagination.urls.next;
var response = UrlFetchApp.fetch(next); // get feed
var json = response.getContentText(); //
var data = JSON.parse(response);
var counter = 100;
for (var i = 0; i< counter; i++) {
var stats = [];
stats.push(data.wants[i].basic_information.title); //works a
stats.push(data.wants[i].basic_information.formats[0].name);
stats.push(String(data.wants[i].basic_information.formats[0].descriptions));
stats.push(data.wants[i].basic_information.labels[0].name); //works c
stats.push(data.wants[i].basic_information.labels[0].catno); // work d
stats.push(data.wants[i].basic_information.year); //l
// stats.push(description); //stringify array?
stats.push(data.wants[i].basic_information.artists[0].name); //works j
stats.push(data.wants[i].basic_information.id); // m
stats.push(data.wants[i].basic_information.resource_url); // m
Logger.log(stats);
SpreadsheetApp.getActiveSpreadsheet().appendRow(stats);
}
}
}
The resource URL is also formatted as http://api.discogs.com/.... Is there a way to convert that to http://www.discogs.com?
Maybe try something like:
stats.push('=HYPERLINK(data.wants[i].basic_information.resource_url,data.wants[i].basic_information.resource_url')
In general what works is to
get the cell
set the value
set the formula (HYPERLINK(...))
setShowHyperlink(true) on the cell.
Hope this helps.
You might aswell checkout this answer: https://stackoverflow.com/a/37488194/1698461
I think you need to wrap data.wants[i].basic_information.resource_url into html tag
like this :
stats.push(
'link'
);
so full code ll be :
function logTheData (url){
var sheet = SpreadsheetApp.getActiveSheet();
var url ='https://api.discogs.com/users/**********/wants?per_page=100';
var response = UrlFetchApp.fetch(url); // get feed
var json = response.getContentText(); //
var data = JSON.parse(response);
var counter = 100;
for (var i = 0; i< counter; i++) {
var stats = [];
stats.push(data.wants[i].basic_information.title); //works a
stats.push(data.wants[i].basic_information.formats[0].name);
stats.push(String(data.wants[i].basic_information.formats[0].descriptions));
stats.push(data.wants[i].basic_information.labels[0].name); //works c
stats.push(data.wants[i].basic_information.labels[0].catno); // work d
stats.push(data.wants[i].basic_information.year); //l
stats.push(data.wants[i].basic_information.artists[0].name); //works j
stats.push(data.wants[i].basic_information.id); // m
stats.push(data.wants[i].basic_information.resource_url); // m
Logger.log(stats);
SpreadsheetApp.getActiveSpreadsheet().appendRow(stats);
}
var pages = data.pagination.pages;
for (var a = 1; a < pages; a++){
var next = data.pagination.urls.next;
var response = UrlFetchApp.fetch(next); // get feed
var json = response.getContentText(); //
var data = JSON.parse(response);
var counter = 100;
for (var i = 0; i< counter; i++) {
var stats = [];
stats.push(data.wants[i].basic_information.title);
stats.push(data.wants[i].basic_information.formats[0].name);
stats.push(String(data.wants[i].basic_information.formats[0].descriptions));
stats.push(data.wants[i].basic_information.labels[0].name);
stats.push(data.wants[i].basic_information.labels[0].catno);
stats.push(data.wants[i].basic_information.year);
stats.push(data.wants[i].basic_information.artists[0].name);
stats.push(data.wants[i].basic_information.id);
stats.push( 'link');
Logger.log(stats);
SpreadsheetApp.getActiveSpreadsheet().appendRow(stats);
}
}
}
I am working with a third-party API (from company called Simpli.fi) in Google Apps Script to pull some data into a spreadsheet. I am able to authenticate my API call just fine and can pull all of my required data with one URL. The issue is that the way the URL to call this API is formatted is as follows:
https://app.simpli.fi/api/organizations/{CLIENT_ID}/{SOME_ENDPOINT}
It works when I plug in one client id and one endpoint, however I do not want to pull the data individually for each client with each data endpoint.
I wish to pull data on all of my clients and also wish to access multiple endpoints, such as "/audiences" or "/campaigns". I am hoping there is a way (similar to Promises in JavaScript) that I can iterate through multiple URLs to fetch all of the data from the API.
For now, I am simply focusing on pulling all the data I want from the "/audiences" endpoint for all of my clients. I have set up an array accessing my Google Sheet that contains all the client codes and have plugged this into the URL with a for loop, which works just fine:
// iterate through all URL endpoints and client codes
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('formatting');
var range = sheet.getRange(['B2:B']).getValues();
var clients = range.filter(String);
var urlOneArray = [];
for (var i = 0; i < clients.length; i++) {
var urlOne = [baseURL + clients[i] + '/audiences'];
for (var j = 0; j < urlOne.length; j++) {
urlOneArray = urlOne[j];
Logger.log(urlOneArray);
}
}
The above logs a list of each built out URL as desired.
After pushing all of the built-out URLs into the urlOneArray, I tried calling with UrlFetchApp.fetchAll:
for (i=0; i < urlOneArray.length; i++) {
var response = UrlFetchApp.fetchAll(urlOneArray[i], params);
Utilities.sleep(500);
Logger.log(response);
}
When trying to use this method, I receive this error:
"Cannot find method fetchAll(string,object). (line 35, file "Code")"
If there is a way to iterate through multiple URLs to gather all of the data from the API in one pull, I would really appreciate some pointers.
Here is the full script:
// authenticate API call
var X_USER_KEY = 'XXXX';
var X_APP_KEY = 'XXXX';
function simplifiService() {
var baseURL = 'https://app.simpli.fi/api/organizations';
// iterate through all URL endpoints and client codes
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('formatting');
var range = sheet.getRange(['B2:B']).getValues();
var clients = range.filter(String);
var urlOneArray = [];
for (var i = 0; i < clients.length; i++) {
var urlOne = [baseURL + clients[i] + '/audiences'];
for (var j = 0; j < urlOne.length; j++) {
urlOneArray = urlOne[j];
Logger.log(urlOneArray);
}
}
var params = {
method: 'GET',
headers: {
"x-app-key": X_APP_KEY,
"x-user-key": X_USER_KEY
},
muteHttpExceptions: true
}
for (i=0; i < urlOneArray.length; i++) {
var response = UrlFetchApp.fetchAll(urlOneArray[i], params);
Utilities.sleep(500);
Logger.log(response);
}
if (response.getResponseCode() === 200) {
var data = JSON.parse(response);
Logger.log(data);
} else {
Logger.log('Error: ' + response.getResponseCode());
}
getData(data);
}
// parse out JSON data
function getData(data) {
var date = new Date();
var geoFenceId = data.audiences;
var geoFenceName = data.audiences[0].name;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Campaign Data');
//sheet.appendRow([date, geoFenceId, geoFenceName]);
}
Issue:
Invalid syntax: UrlFetchApp.fetchAll(requests Object[]) accepts object array, while you're providing a string and a object as argument.
Solution:
Valid Syntax: Create a object array for each endpoint/client and provide it as a argument to fetchAll()
Snippet:
function copyParams() {//shallow clone params object
for (var i in params) {
this[i] = params[i];
}
}
var endPoints = ['/audiences', '/campaigns'];
var requests = [];
var url, obj;
clients.forEach(function(client) {
endPoints.forEach(function(endPoint) {
obj = new copyParams();
url = baseUrl + '/' + client[0] + endPoint;
obj.url = url;
requests.push(obj);
});
});
console.log(requests);
var responseArray = UrlFetchApp.fetchAll(requests);
console.log(responseArray);
References:
UrlFetchApp.fetchAll
Array#forEach
I need to store XML data to a hashmap, I'm using nodejs and xmldom npm module to parse the XML.
I'm trying to store the testsuite name, testcase name and dt_value in a hashmap.
here is my XML code
<testscenario>
<testsuite name="com.edge.route">
<testcase name="tc_Login">dt_Login</testcase>
<testcase name="tc_Logout">dt_Logout</testcase>
</testsuite>
<testsuite name="com.edge.beacon">
<testcase name="tc_Channel">dt_Channel,dt_Logout</testcase>
</testsuite>
</testscenario>
Here's what I have tried so far
var DOMParser = require('xmldom').DOMParser;
var parser = new DOMParser();
var HashMap = require('hashmap');
var fs = require('fs');
module.exports = {
testScenario: function() {
var suiteName;
var data;
var map = new HashMap();
//read the testscenario.xml
data = fs.readFileSync("./testscenario.xml", "utf8");
var dom = parser.parseFromString(data);
var testSuiteList = dom.getElementsByTagName("testsuite");
//loop through all the test suites
for (i = 0; i < testSuiteList.length; i++) {
//select the test suite with the given name
suiteName = testSuiteList[i].getAttribute("name");
var tcList = testSuiteList[i].getElementsByTagName("testcase");
var dtList = testSuiteList[i].getElementsByTagName("testcase")[0].childNodes[0].nodeValue;
console.log(dtList)
//get the row count
tcLength = tcList.length;
//push column headers as the key in the hashmamp
var testCaseList = [];
for (x = 0; x < tcList.length; x++) {
testCaseList.push(tcList[x].getAttribute("name"));
}
console.log(testCaseList)
var dataTableList = [];
for (i = 0; i < tcLength; i++) {
dataTableList += tcList[i].childNodes[0].nodeValue;
}
console.log("dtlist = " + dataTableList);
//push the row values as an array to the hashmap
map.set(suiteName, testCaseList);
}
return [map]
}
};
I'm able to get the key, value pair for testsuite and testcase but I also need to get the dt_name. how can I modify this code to store the dt_name along with testsuite and testcase names in that hashmap?
Alright figured it out. This is how I did it. I have used a hashmap within a hashmap
//XML Reader
var DOMParser = require('xmldom').DOMParser;
var parser = new DOMParser();
var HashMap = require('hashmap');
var fs = require('fs');
module.exports={
testScenario: function ()
{
var suiteName;
var data;
var map = new HashMap();
//read the testscenario.xml
data=fs.readFileSync("./testscenario.xml","utf8");
var dom = parser.parseFromString(data);
var testSuiteList = dom.getElementsByTagName("testsuite");
//loop through all the test suites
for (i=0;i< testSuiteList.length; i++) {
//select the test suite with the given name
suiteName = testSuiteList[i].getAttribute("name");
var tcList = testSuiteList[i].getElementsByTagName("testcase");
//get the row count
Length=tcList.length;
//push column headers as the key in the hashmamp
var testCaseList = new HashMap();
for(x=0;x<Length;x++)
{
testCaseList.set(tcList[x].getAttribute("name"),tcList[x].childNodes[0].nodeValue);
}
//push the row values as an array to the hashmap
map.set(suiteName,testCaseList);
}
return [map]
}
};
I use the code below to retrieve a XML and write the data to Sheet2.
But when i run the function again it loads the entire xml again into the sheet.
What i want to achieve, but don't know how:
1.
Get de XML and compare it with the data already in Sheet2, based on 2 colums:
stationID & stationTypeID
2.
When the two columns match, update the entire row. When the columns don't match, insert the new row on top.
function loadOutposts(){
var outposts= new Array();
var url = "https://api.eveonline.com/eve/ConquerableStationList.xml.aspx";
var parameters = {method : "get", payload : ""};
var xmlFeed = UrlFetchApp.fetch(url, parameters).getContentText();
var xml = XmlService.parse(xmlFeed);
if(xml) {
var rows=xml.getRootElement().getChild("result").getChild("rowset").getChildren("row");
for(var i = 0; i < rows.length; i++) {
outpost=[rows[i].getAttribute("stationID").getValue(),
rows[i].getAttribute("stationName").getValue(),
rows[i].getAttribute("stationTypeID").getValue(),
rows[i].getAttribute("solarSystemID").getValue(),
rows[i].getAttribute("corporationID").getValue(),
rows[i].getAttribute("corporationName").getValue()
]
outposts.push(outpost);
}
}
//return outposts;
SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet2').getRange(1,1,outposts.length,outposts[0].length).setValues(outposts);
};
Thx for the help!
How about this modification?
Flow :
Data retrieved by UrlFetchApp.fetch() is compared to the existing data on Spreadsheet.
When the columns 1 and 2 for them are same, the existing data is updated.
When the data retrieved from URL is not included in the existing data, the data is inserted to the top of existing data. This existing data becomes new data.
Then, the data on Spreadsheet is updated by new data.
Modified script :
function loadOutposts(){
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet2');
var outposts= new Array();
var url = "https://api.eveonline.com/eve/ConquerableStationList.xml.aspx";
var parameters = {method : "get", payload : ""};
var xmlFeed = UrlFetchApp.fetch(url, parameters).getContentText();
var xml = XmlService.parse(xmlFeed);
if (xml) {
var rows=xml.getRootElement().getChild("result").getChild("rowset").getChildren("row");
for(var i = 0; i < rows.length; i++) {
outpost = [
rows[i].getAttribute("stationID").getValue(),
rows[i].getAttribute("stationName").getValue(),
rows[i].getAttribute("stationTypeID").getValue(),
rows[i].getAttribute("solarSystemID").getValue(),
rows[i].getAttribute("corporationID").getValue(),
rows[i].getAttribute("corporationName").getValue()
]
outposts.push(outpost);
}
// ----- Added script
if (ss.getLastRow() > 0) {
var currentdata = ss.getRange(2, 1, ss.getLastRow(), ss.getLastColumn()).getValues(); // Updated
currentdata.forEach(function(e1, i1){
var temp = [];
outposts.forEach(function(e2, i2){
if (e1[0] == e2[0] && e1[1] == e2[1]) {
currentdata[i1] = e2;
temp.push(i2);
}
});
for (var i in temp) {
outposts.splice(temp[i], 1);
}
});
Array.prototype.push.apply(outposts, currentdata);
}
// -----
}
ss.getRange(2,1,outposts.length,outposts[0].length).setValues(outposts); // Updated
};
If I misunderstand your question, I'm sorry.
I want to sort results obtained from indexedDB.
Each record has structure {id, text, date} where 'id' is the keyPath.
I want to sort the results by date.
My current code is as below:
var trans = db.transaction(['msgs'], IDBTransaction.READ);
var store = trans.objectStore('msgs');
// Get everything in the store;
var keyRange = IDBKeyRange.lowerBound("");
var cursorRequest = store.openCursor(keyRange);
cursorRequest.onsuccess = function(e) {
var result = e.target.result;
if(!!result == false){
return;
}
console.log(result.value);
result.continue();
};
Actually you have to index the date field in the msgs objectStore and open an index cursor on the objectStore.
var cursorRequest = store.index('date').openCursor(null, 'next'); // or prev
This will get the sorted result. That is how indexes are supposed to be used.
Here's the more efficient way suggested by Josh.
Supposing you created an index on "date":
// Use the literal "readonly" instead of IDBTransaction.READ, which is deprecated:
var trans = db.transaction(['msgs'], "readonly");
var store = trans.objectStore('msgs');
var index = store.index('date');
// Get everything in the store:
var cursorRequest = index.openCursor();
// It's the same as:
// var cursorRequest = index.openCursor(null, "next");
// Or, if you want a "descendent ordering":
// var cursorRequest = index.openCursor(null, "prev");
// Note that there's no need to define a key range if you want all the objects
var res = new Array();
cursorRequest.onsuccess = function(e) {
var cursor = e.target.result;
if (cursor) {
res.push(cursor.value);
cursor.continue();
}
else {
//print res etc....
}
};
More on cursor direction here: http://www.w3.org/TR/IndexedDB/#cursor-concept
IDBIndex API is here: http://www.w3.org/TR/IndexedDB/#idl-def-IDBIndex
Thanks to zomg, hughfdjackson of javascript irc, I sorted the final array. Modified code as below:
var trans = db.transaction(['msgs'], IDBTransaction.READ);
var store = trans.objectStore('msgs');
// Get everything in the store;
var keyRange = IDBKeyRange.lowerBound("");
var cursorRequest = store.openCursor(keyRange);
var res = new Array();
cursorRequest.onsuccess = function(e) {
var result = e.target.result;
if(!!result == false){
**res.sort(function(a,b){return Number(a.date) - Number(b.date);});**
//print res etc....
return;
}
res.push(result.value);
result.continue();
};