Read complex JSON in pure Javascript - javascript

I have the following json object and I would like to read it (access some data from it)
how can I do it in Javascript please ?
var allSites =
{"oldSites":
[
{
"site0" : "http://site0.com/",
"site1" : "http://site1.com/",
"site2" : "http://site2.com/"
}
],
"newSites":
[
{
"site0" : "http://site0/new",
"site1" : "http://site1/new",
"site2" : "http://site2/new"
}
]
};
This is what I did but I get undefined.
var allSites = eval(allSites);
alert(allSites.oldSites.site0);
Thanks.

If your object is defined like you have described, it is not JSON, you do not need to use eval.
Then, since oldSites is an array, you have to index it, like oldSites[0] to get the first value.
Then, get the site0 key of the object retrieved.
So you should use: allSites.oldSites[0].site0

Use
allSites.oldSites[0].site0
allSites.oldSites is an array. So you have to iterate using index

Please remove the square brackets which make oldSites an array
var allSites =
{"oldSites":
{
"site0" : "http://site0.com/",
"site1" : "http://site1.com/",
"site2" : "http://site2.com/"
}
,
"newSites":
{
"site0" : "http://site0/new",
"site1" : "http://site1/new",
"site2" : "http://site2/new"
}
};

Related

How to add an object as a data attribute

Using the api I was able to retrieve the info i needed trough the following endpoints and create the following object.
var lego = {
"name" : item.name,
"followers" : item.follower_count,
"created" : item.created_at,
"updated" : item.updated_at
}
<datagrid id = "topicGrid" data='[{}]'>
<datagrid-column head="Topic" content-key="name"></datagrid-column>
<datagrid-column head="Followers" content-key="followers"></datagrid-column>
<datagrid-column-time head="Created" content-key="created" format="date"></datagrid-column-time>
<datagrid-column-time head="Updated" content-key="updated" format="date"></datagrid-column-time>
</datagrid>
I would like to somehow append the "lego" object in the new data attribute ?
Now i tried something like
setAttribute("data", lego); but my knowledge here is limited.
Any help is apreciated. Thank you.
Update:
I tried passing the object as a string but I only get the last element of the object. Kind of like it's looping trough the whole object and stopping at the last one.
$('datagrid').attr('data', JSON.stringify(lego));
My solution
$.get( "..." ).done(function( data ) {
var legoArr = []
$.each(data.topics, function(index,item) {
var lego = {
"name" : item.name,
"followers" : item.follower_count,
"created" : item.created_at,
"updated" : item.updated_at
};
legoArr.push(lego);
});
$('datagrid').attr('data', JSON.stringify(legoArr));
});

Need to search API output in JSON format for value and print entire array content

I have googlesheets functions that parse json and import to sheets, you can find the code for the function in ImportJson file.
function IMPORTJSON(url,xpath){
try{
// /rates/EUR
var res = UrlFetchApp.fetch(url);
var content = res.getContentText();
var json = JSON.parse(content);
var patharray = xpath.split("/");
//Logger.log(patharray);
for(var i=0;i<patharray.length;i++){
json = json[patharray[i]];
}
//Logger.log(typeof(json));
if(typeof(json) === "undefined"){
return "Node Not Available";
} else if(typeof(json) === "object"){
var tempArr = [];
for(var obj in json){
tempArr.push([obj,json[obj]]);
}
return tempArr;
} else if(typeof(json) !== "object") {
return json;
}
}
catch(err){
return "Error getting data";
}
}
The functions is pretty simple and self explanatory . Disclosure I got this function from here. "https://www.youtube.com/watch?v=EXKhVQU37WM"
I had some additional requirements that this function cannot do. Need to search API output in JSON format for value and print entire array content.
For example I had a JSON output as below .
{
"symbol" : "AAPL",
"historicalDCF" : [ {
"date" : "2019-03-30",
"Stock Price" : 190.5064,
"DCF" : 199.51439324614452
}, {
"date" : "2018-12-29",
"Stock Price" : 156.4638,
"DCF" : 165.25974241335186
}, {
"date" : "2018-09-29",
"Stock Price" : 224.6375,
"DCF" : 233.0488839004929
}, {
"date" : "2018-06-30",
"Stock Price" : 184.3734,
"DCF" : 192.36145120758877
}, {
"date" : "2018-03-31",
"Stock Price" : 163.5502,
"DCF" : 172.0839412239145
}, {
"date" : "2017-12-30",
"Stock Price" : 168.339,
"DCF" : 178.05212237708827
}, {
"date" : "2017-09-30",
"Stock Price" : 149.7705,
"DCF" : 160.23613044781487
}, {
"date" : "2017-07-01",
"Stock Price" : 139.1847,
"DCF" : 150.3852802404117
}, {
"date" : "2017-04-01",
"Stock Price" : 138.8057,
"DCF" : 148.7456306248566
}, {
"date" : "2016-12-31",
"Stock Price" : 111.7097,
"DCF" : 120.02897160465633
}, {
"date" : "2016-09-24",
"Stock Price" : 108.0101,
"DCF" : 116.70616209306208
}
]
}
You can also check live version of this API on this link " https://financialmodelingprep.com/api/v3/company/historical-discounted-cash-flow/AAPL?period=quarter"
To get DCF value on "2019-03-30", I can simply use functions as this:
=IMPORTJSON("https://financialmodelingprep.com/api/v3/company/historical-discounted-cash-flow/AAPL?period=quarter","historicalDCF/0/DCF")
What if I need to search through date and get the value of Stock Price? For example I need to get the value of Stock price and DCF on this date "2017-09-30" . How could I do it without knowing array position ?
So for this I need help either by creating new function or modifying existing function to get this functionality.
Help is highly appreciated and thanks in advance to all the gurus out there.
json.historicalDCF.filter((el) => el.date === "2017-07-01") will return the object that matches that date.
You could get the return like:
function findByDate(dateParam) {
return json.historicalDCF.filter((el) => el.date === dateParam)
}
var theInfoIWantVariable = findByDate("2017-1-1-make-sure-this-is-a-string")
Given that your IMPORT function is returning a JSON object (and assuming the format is what you've shown in your post), then you could simply use a regular javascript filter() function to get the specific date you want:
const data =IMPORTJSON("https://financialmodelingprep.com/api/v3/company/historical-discounted-cash-flow/AAPL?period=quarter","historicalDCF");
// now, data is the JSON array containing the historical data. All the data. We can filter it for whatever we want.
const myOneDayRecord = data.find( record => record.date === '2016-03-30' );
// so the variable myOneDayRecord is the specific record by date we wanted. Now we can use it as a normal javascript object.
console.log(`So on ${myOneDayRecord.date}, the stock price was ${myOneDayRecord["Stock Price"] } and the DCF was ${myOneDayRecord.DCF}`);
// note that, in the above line,I had to use bracket notation to get to the 'Stock Price' property. That's because of the space in the property name.
If I understood you correctly, you want to create a custom function that will:
Accept a url, a xpath and a date as a parameter.
Call IMPORTJSON and pass the previous url and xpath as parameters.
In the JSON returned by IMPORTJSON, find the item in historicalDCF whose date matches the one passed as a parameter.
Return its corresponding Stock Price.
If all of the abose is correct, then you could do something along the following lines:
function GETSTOCKPRICE(url, xpath, date) {
var jsonData = IMPORTJSON(url,xpath);
var historical = jsonData["historicalDCF"];
var stockPrice;
for (var i = 0; i < historical.length; i++) {
if (historical[i]["date"] === date) {
stockPrice = historical[i]["Stock Price"];
break;
}
}
return stockPrice;
}
And then, you can use this function in your sheet by passing it the correct parameters. For example, if you want to get the stock price corresponding to 2017-09-30:
=GETSTOCKPRICE("https://financialmodelingprep.com/api/v3/company/historical-discounted-cash-flow/AAPL?period=quarter", "historicalDCF/0/DCF", "2017-09-30")
Notes:
Methods like filter or find, arrow functions and declarations like const won't work here, since Apps Script doesn't currently support ES6.
You could also modify GETSTOCKPRICE so that it only accepts date as a parameter, and the call to IMPORTJSON has its parameters hard-coded (this would make sense if you're always going to use IMPORTJSON for this exact url and xpath). But that's up to you.
I hope this is of any help.

JSON parsing using jQuery is not working

I have a JSON which is like this-
var json = {
"http://data.abc.net/uml/extensions#0001" : {
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
"type" : "literal" ,
"location" : "ASIA" ,
"datatype" : "http://www.w3.org/2001/XMLSchema#string"
}]
}
,
"http://data.abc.net/uml/extensions#0002" : {
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
"type" : "literal" ,
"location" : "EUROPE" ,
"datatype" : "http://www.w3.org/2001/XMLSchema#string"
}]
}
}
I am trying to parse this using JQUERY and want to store the values ASIA and EUROPE in an array called allREgions. I have written a code like this-
var allRegions = [];
var output = $.parseJSON(json);
var list = output.data;
$.each(list,function(index, val){
allRegions.push(val.location);
});
But this is not working. What is going wrong in here?
Your first problem is that you do not have JSON. You have a JavaScript object literal. You don't need to parse it (because parsing JSON converts JSON into an object), and trying to do so will first convert it to a string (which wouldn't be valid JSON).
Replace var output = $.parseJSON(json); with var output = json;.
Your second problem is that you don't have a data property in the object. Your properties are http://data.abc.net/cib/cia/uml/extensions#0001 and http://data.abc.net/cib/cia/uml/extensions#0002
Replace var list = output.data; with var list = output.
You can skip both those steps and just apply the data to the right thing in the first place.
Your third problem is that when you loop over them, your values are objects with one property (http://www.w3.org/2000/01/rdf-schema#label) so you can't access location.
To get to that you have to read the value of that property, then get the first index of the array that its value is, and then access the location of that.
var data = {
"http://data.abc.net/cib/cia/uml/extensions#0001": {
"http://www.w3.org/2000/01/rdf-schema#label": [
{
"type": "literal",
"location": "ASIA",
"datatype": "http://www.w3.org/2001/XMLSchema#string"
}
]
},
"http://data.abc.net/cib/cia/uml/extensions#0002": {
"http://www.w3.org/2000/01/rdf-schema#label": [
{
"type": "literal",
"location": "EUROPE",
"datatype": "http://www.w3.org/2001/XMLSchema#string"
}
]
}
}
var allRegions = [];
$.each(data,function(index, val){
allRegions.push(val['http://www.w3.org/2000/01/rdf-schema#label'][0].location);
});
you dont need to use $.parseJSON, just do:
var allRegions = [];
$.each(json, function(idx, val) {
$.each(val, function(idxSec, valSec) {
allRegions.push(valSec[0].location);
});
});
console.log(allRegions);
jsFiddle demo

Global variables to pull from an associative array/object?

I have 50 dots on a page, each individual divs. When I click one, I want to use the ID to pull values out of an array. I can get the ID but I'm having trouble using that value to get stuff out of my array. Perhaps a global variable problem? Not sure. Not even sure if this is the best way to handle multiple clicks that access multiple data. Any help is appreciated!
var location0 = {"name" : "Location 1", "image" : "image1.jpg"};
$('.dot').click(function(){
var thisLocation = $(this).attr("id");
alert(thisLocation); //Returns "location0"
alert(thisLocation["image"]); //Returns "undefined"
});
Here's a fiddle.
I'd do it like this :
var locations = {
location1 : {"name" : "Location 1", "image" : "image1.jpg"},
location2 : {"name" : "Location 2", "image" : "image2.jpg"}
}
$('.dot').click(function(){
alert(locations[this.id].name);
});
​
FIDDLE
$(this).attr("id") returns a String "location0". If you want to use it you have to get an actual location0 variable, so you have to replace one of your code lines using eval() function. like this:
var thisLocation = eval($(this).attr("id"));
I would however recommend using a new array, where "location0" would be a key, then you would just need to access a key with a string like locations["location0"] and avoid using eval().
you need to access it like this:
var test = {
location0: {"name" : "Location 1", "image" : "image1.jpg"}
};
$('.dot').click(function(){
var thisLocation = $(this).attr("id");
alert(thisLocation); //Returns "location0"
alert(test[thisLocation]["image"]); //Returns "undefined"
});
​
edit: this works
Also the reason why it doesn't work for you at first place is because thisLocation is a string, not an object it self, so you need to use brackets to access objects property by passing name. I just wouldn't advice

How to read JSON(server response) in Javascript?

I am sending some request on a server and it's reply me this:
{"COLUMNS":["REGISTRATION_DT","USERNAME","PASSWORD","FNAME","LNAME","EMAIL","MOBILE","FACEBOOK_ID"],"DATA":[["March, 17 2012 16:18:00","someuser",somepass,"somename","somesur","someemail",sometel,"someid"]]}
I tried a lot but nothing seems to working for me!
var xml2 = this.responseData;
var xml3 = xml2.getElementsByTagName("data");
Ti.API.log(xml3.FNAME);
For this code I get "null".
Any help would be appreciated!
If you're trying to use JSON format, your problem is that the data within the [...] also needs to be in pairs, and grouped in {...} like here.
For instance,
{
"sales": [
{ "firstname" : "John", "lastname" : "Brown" },
{ "firstname" : "Marc", "lastname" : "Johnson" }
] // end of sales array
}
So you might have:
{"COLUMNS": [
{"REGISTRATION_DT" : "19901212", "USERNAME" : "kudos", "PASSWORD" : "tx91!#1", ... },
{"REGISTRATION_DT" : "19940709", "USERNAME" : "jenny", "PASSWORD" : "fxuf#2", ... },
{"REGISTRATION_DT" : "20070110", "USERNAME" : "benji12", "PASSWORD" : "rabbit19", ... }
]
}
If the server is sending you something which you refer to as res, you can just do this to parse it in your Javascript:
var o=JSON.parse(res);
You can then cycle through each instance within columns like follows:
for (var i=0;i<o.COLUMNS.length;i++)
{
var date = o.COLUMNS[i].REGISTRATION_DT; ....
}
see that link. READ JSON RESPONSE
It's perfect.
JSON objects work just like any normal javascript objects or dictionaries
// You can do it this way
var data = this.responseData["DATA"]
// Or this way
var data = this.responseData.DATA
In your case, COLUMNS and data are both arrays, so it looks like you're trying to get the element from data that corresponds to the "FNAME" element in COLUMNS?
var columns = this.responseData["COLUMNS"];
var data = this.responseData["DATA"][0];
for(var i=0; i<columns.length; i++){
if(columns[i] == "FNAME"){
Ti.API.log(data[i]);
}
}
EDIT: If you can't change the data on the server end, you can make your own object client side. This also helps if you have to refer to multiple columns (which you probably do).
var columns = this.responseData["COLUMNS"];
var data = this.responseData["DATA"][0];
var realData = {};
for(var i=0; i<columns.length; i++){
realData[columns[i]] = data[i];
}
// Now you can access properties directly by name.
Ti.API.log(data.FNAME);
More edit:
My answers only consider the first row in DATA, because I misread originally. I'll leave it up to you to figure out how to process the others.
If you got here trying to find out how to read from [Response object] (as I did) -
this what can help:
- if you use fetch don't forget about res.json() before logging in console
fetch(`http://localhost:3000/data/${hour}`, {
method: 'get'
})
.then(res => {
return res.json()
})
.then((response) => {
console.log('res: ' + JSON.stringify(response))
})
Testing out your code in http://jsonlint.com/, it says that your server's response is not a valid JSON string.
Additionally, I recommend checking out jQuery.parseJSON http://api.jquery.com/jQuery.parseJSON/
Just use JSON.parse(serverResponse)

Categories

Resources