Get value of object field using variables to build the field name - json

I am using a free currency converter API as shown in the code:
// Free Currency Converter
url = 'https://free.currencyconverterapi.com/api/v5/convert?q=EUR_USD&compact=ultra';
response = UrlFetchApp.fetch(url);
rateEURUSD_FCC_JSON = JSON.parse(response.getContentText());
rateEURUSD_FCC = rateEURPLN_FCC_JSON.EUR_USD;
Logger.log('rateEURUSD_FCC = ' + rateEURUSD_FCC);
And that works well.
Now I want to use the same method but in a function taking currency1 and currency2 as inputs.
url = 'https://free.currencyconverterapi.com/api/v5/convert?q='+Currency1+'_'+Currency2+'&compact=ultra';
response = UrlFetchApp.fetch(url);
fiatRate_FCC_JSON = JSON.parse(response.getContentText());
fiatPairName = Object.keys(fiatRate_FCC_JSON);
I can see the name of the key created in the object but I do not know how to get the value of that element (that key?).
theValue = fiatRate_FCC_JSON.xxxxxxxxxxxxxxxxxxxxx
I think I need to use currency1 and currency2 to build the name of the field I want to access but I do not know how to do this.
Can anyone help?
Yes, I have tried looking on google and through the forum's search tool so please do not direct me back there if that would be your only contribution. Thanks.
EDIT:
This worked
theValue = fiatRate_FCC_JSON[Currency1+'_'+Currency2];
Thanks Tanaike.

How about this?
theValue = fiatRate_FCC_JSON[Currency1+'_'+Currency2];
If this didn't work, please tell me. I would like to modify.

I think that can help you also
var theValue = fiatRate_FCC_JSON[fiatPairName[0]]

Related

how to do to retrieve person.photos[0].default?

I tried to retrieve the variable Default from json of people api but it doesn't work with "default" . how to do it ? thank you for your answer
see my test script below, please (last line at bottom)
var person = People.People.get('people/' + accountId, {personFields: 'names,photos,phoneNumbers,addresses,birthdays,sipAddresses,organizations,genders'});
//** var val_displayName_P = person.names[0].displayName;
var val_photoUrl = person.photos[0].url.replace("=s100","=s128");
var primary_BLN = person.photos[0].metadata.primary;
var default_BLN = person.photos[0].default;
Seems like it is not returning default field in JSON response when a particular accountID contains user-provided photo(default : false), looks like a bug to me, not sure.
In case of User-provided photo, this is the log i am getting :-
And in case of default photo:-
Maybe that's why execution is breaking at last line.
If this is the case, for now you can try this :-
const photo= person.photos[0]
var default_BLN = photo.hasOwnProperty('default') ? photo.default : false;
Reference:
Photo
JSON is case sensitive, try person.photos[0].Default.

Why is this Importxml formula not working?

The following formula does work for some, but not for others:
=IFNA(VALUE(IMPORTXML("https://finance.yahoo.com/quote/C2PU.SI", "//*[#class=""D(ib) Mend(20px)""]/span[1]")))
If used without IFNA, it says 'Resource at url not found'.
Here's the value I'm trying to pull in:
I appreciate if you could point me to the right direction.
Thank you!
It does not return any values even for simple importxml.
It seems the site is generated by javascript or protected so it can't be scraped by importxml.
Don't use the "inspect" tool as it will show the DOM as it's being rendered by the web browser including modifications to the source code by client-side JavaScript, instead look at the source code.
Resources
How to know if Google Sheets IMPORTDATA, IMPORTFEED, IMPORTHTML or IMPORTXML functions are able to get data from a resource hosted on a website?
The structure of the DOM is generated by javascript. Nevertheless, all informations you need are contained by a json string called here root.App.main. You can get all the data by these way
function extract(url){
var source = UrlFetchApp.fetch(url).getContentText()
return source.match(/(?<=root.App.main = ).*(?=}}}})/g) + '}}}}'
}
and then retrieve the data by conventionnal json parsing. This will give you the value
[![function marketPrice() {
var code = 'C2PU.SI'
var url='https://finance.yahoo.com/quote/' + code
var source = UrlFetchApp.fetch(url).getContentText()
var jsonString = source.match(/(?<=root.App.main = ).*(?=}}}})/g) + '}}}}'
var data = JSON.parse(jsonString)
var regularMarketPrice = data.context.dispatcher.stores.StreamDataStore.quoteData.item(code).regularMarketPrice.raw
Logger.log(regularMarketPrice)
}
Object.prototype.item=function(i){return this\[i\]};][1]][1]

Parse JSON data from ASX into Google Sheets for Exchange Traded Products - not companies

I am trying to develop a Google Sheets-based portfolio tracking sheet that is able to retrieve daily prices for the securities in the Australian (ASX) and US markets.
For US market securities the GoogleFinance function works well enough. However for the ASX the ability for GoogleFinance to retrieve information is a bit hit and miss.
Ruben had asked a similar question to which Ian Finlay provided a solution that works in most instances, i.e. listed companies, but not for Exchange Traded Products that such as PMGOLD.
Ian Finlay's solution using apps script to parse json data was:
<code>
function AsxPrice(asx_stock) {
var url = "https://www.asx.com.au/asx/1/share/" + asx_stock +"/";
var response = UrlFetchApp.fetch(url);
var content = response.getContentText();
Logger.log(content);
var json = JSON.parse(content);
var last_price = json["last_price"];
return last_price;
}
For a 'normal' company such as NAB = asx_stock, the script works well, however for a exchange traded product such as PMGOLD, it does not.
With some basic searching an experimentation, the reason seems to be that the url that is in the script does not point to the information required.
For NAB = asx_stock, the url reponse is
{"code":"NAB","isin_code":"AU000000NAB4","desc_full":"Ordinary Fully Paid","last_price":23.77,"open_price":24.11,"day_high_price":24.21,"day_low_price":23.74,"change_price":-0.15,"change_in_percent":"-0.627%","volume":1469971,"bid_price":23.75,"offer_price":23.77,"previous_close_price":23.92,"previous_day_percentage_change":"-1.239%","year_high_price":27.49,"last_trade_date":"2021-01-29T00:00:00+1100","year_high_date":"2020-02-20T00:00:00+1100","year_low_price":13.195,"year_low_date":"2020-03-23T00:00:00+1100","year_open_price":34.51,"year_open_date":"2014-02-25T11:00:00+1100","year_change_price":-10.74,"year_change_in_percentage":"-31.121%","pe":29.12,"eps":0.8214,"average_daily_volume":6578117,"annual_dividend_yield":2.51,"market_cap":-1,"number_of_shares":3297132657,"deprecated_market_cap":78636614000,"deprecated_number_of_shares":3297132657,"suspended":false}
However, for PMGOLD = asx_stock, the url reponse is:
{"code":"PMGOLD","isin_code":"AU000PMGOLD8","desc_full":"Perth Mint Gold","suspended":false}
Conducting some relatively 'non-code qualified person' type research, looks like the actual url for an Exchange Listed Product should be:
https://www.asx.com.au/asx/1/share/PMGOLD/prices?interval=daily&count=1
The url reponse for this is:
{"data":[{"code":"PMGOLD","close_date":"2021-01-28T00:00:00+1100","close_price":24.12,"change_price":0.19,"volume":98132,"day_high_price":24.2,"day_low_price":23.9,"change_in_percent":"0.794%"}]}
When I substitute this url into Ian Finlay's code and rename the var as 'close_price' instead of 'last_price' there is nothing retrieved. The code used is:
function AskPrice(asx) {
var url = "https://www.asx.com.au/asx/1/share/"+ asx +"/prices?interval=daily&count=1";
var response = UrlFetchApp.fetch(url);
var content = response.getContentText();
Logger.log(content);
var json = JSON.parse(content);
var data = json["data"];
return data;
}
I suspect this is due to the structure of the url response being formatted differently for the two different url types. Maybe nested? - I am not sure.
Can someone please help point out what mistake(s) I am making?
Thank you
Yes, the structure is different. I've done this in Python so I know exactly your problem.
The 1/share API (first example) returns a simple dictionary of name:value pairs so you can easily reference the value.
The "prices" version gives you a list of daily values under the data element. Even though your example only returns one day, it is a list with one value. (Notice the [square] brackets around it?
So you need to go to the "data" element to get the list, then reference the first (only) item of the list and then reference close_price.
I don't know this language but it's probably something like:
var data = json["data"][0]["close_price"];
Let me know if this helps.

DriveApp.createFile( e.parameter.blob); Not executing

In google app scripts, the following line throws error:
DriveApp.createFile( e.parameter.fileupBlob);
Where fileupBlob is hidden field in the form with a BLOB stored in it.
Error thrown when executed:
Cannot find method createFile((class)). (line 23, file "Code", project
"saving")
The argument of DriveApp.createFile must be a blob.
The value returned by e.parameter.varName is a string.
Therefore the error you get. The only case when a blob is returned from a form is when you use a file upload widget, the hidden widget behaves like a text widget.
You need to create the blob as shown below. It is assuming you passed a valid blob. EDIT: If drive is having difficulty figuring out what type of file it is from the blob you can provide that info yourself. Another thought is that the blob may be base64 encoded. You may have to decode it before creating the new blob. You haven't posted any code so I can't tell what is going on.
var name = "fileName.png";
var contentType = "image/png";
var fileBlob = Utilities.newBlob(e.parameter.fileupBlob, contentType, name);
DriveApp.createFile(fileBlob);
Do this
let imageBlob = images[0].getBlob();
let name = 'fileName.jpeg';
let contentType = 'image/jpeg';
let fileBlob = Utilities.newBlob(imageBlob.getBytes(), contentType, name);
let imageFile = folder.createFile(fileBlob).setName('ravgeet.jpeg');
Got it! The javascript library was returning string dataURI and i replaced the first part of dataURI in jquery:
strDataURI=strDataURI.replace("data:image/png;base64,", "");
document.getElementById("blobobj").value = strDataURI;
Then i was able to create the image
var str=Utilities.base64Decode(e.blobobj);
var fileBlob = Utilities.newBlob(str).setContentType('image/png');

How to extract links from an inframe?

what I'm trying to do is extract link(s) from a google ad box, I tried it with jQuery and I'm getting an error when trying to run it, here's the code:
var iframe = document.getElementById("aswift_0");
var iframeDoc = iframe.contentDocument || iframe.contentWindow;
// Get HTML element
var iframeHtml = iframeDoc.getElementsByTagName("iframe")[1];
$(iframeHtml).contents().find("textarea").keydown(...)
var iframeDoc2 = iframeHtml.contentDocument ||
iframeHtml.contentWindow;
var iframeHtml2 = iframeDoc2.getElementsByTagName("body");
I get this error because I can't access the cross domain, I read that it's possible to extract the link(s) using JSONP callback function or post message, does, can someone help me with the code or know how to extract a link from an inframe. Thanks in advance.
You can't do that. This is cross domain access and your browser will block it.