simple ajax request to load external json file - javascript

I'm learning ajax.... I am trying to make a basic request from a json file, which is in the same folder as my index.html, but for some reason it says undefined :( I can see the error is on the variable people, but I can't catch why it's undefined....
html:
<div id="personName"></div>
javascript:
var xhr = new XMLHttpRequest(); //it holds the ajax request
xhr.onreadystatechange = function() { //callback
if(xhr.readyState === 4) {
var people = JSON.parse(xhr.responseText);//it takes the string from the response and it converts it in a javascript object
console.log(people);
for (var i=0; i<people.length; i += 1) {
var htmlCode = "<p>" + people[i].name + "</p>";
}
document.getElementById('personName').innerHTML = htmlCode;
} else {
console.log(xhr.readyState);
}
};
xhr.open('GET', 'addresses.json');
xhr.send();
addresses.json:
{
"people": [
{
"position" : "1",
"name" : "Familia Molina Fernandez",
"streetType" : "C/",
"streetName " : "Nuria",
"streetNumber" : "40",
"floor" : "",
"flat" : "",
"zipCode" : "08202",
"city" : "Sabadell",
"state" : "Barcelona",
"country" : "Spain"
},
{
"position" : "2",
"name" : "Familia Astals Fernandez",
"streetType" : "Avda/",
"streetName " : "Polinya",
"streetNumber" : "61",
"floor" : "1",
"flat" : "1",
"zipCode" : "08202",
"city" : "Sabadell",
"state" : "Barcelona",
"country" : "Spain"
}
]
}
Any ideas?
Cheers!!!!

Try console.log(people); and take a look at the object to which your variable refers. (Hint: it's not what you think it is!)
Your variable people refers to an object with only one attribute named "people". That attribute is an array. So with that JSON structure, your code could be written:
var data = JSON.parse(...)
var people = data.people;
(alternatively, I might redesign the JSON and remove the extra level of indirection: just encode the array itself without wrapping it in an object that contains nothing else)

Related

JSON root elements and encoding

I'm having a JSON deserialized from Java as follow:
Java
jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(graphDTO);
JSON
"accounts" : [ {
"name" : "1009427721",
"value" : 16850.79,
"children" : [ {
"name" : "BITCOIN EARNINGS",
"value" : 10734.24,
"children" : [ {
"name" : "2017",
"value" : 1037.82,
"children" : [ {
"name" : "07",
"value" : 518.91
} ]
} ]
}, ...
The deserialized Java POJO being:
public class GraphDTO {
private Set<Account> accounts = new HashSet<>();
public Set<Account> getAccounts() {
return accounts;
}
}
Questions
How can I remove "accounts" from the generated JSON (first line) ?
Injecting the JSON form into JavaScript, I'm getting an encoded form like:
var data = { "accounts" : [ { ...
How can I avoid this ?
I don't think it's possible to avoid the accounts, but you can do this:
jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(graphDTO.getAccounts());
We're waiting your way to parse JSON in javascript...
Got it work as follow:
Applying the answer of Mohicane:
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(graphDTO.getAccounts())
Injecting the JSON from Java to JavaScript (in a JSP) with:
var data = ${graphDTOJSON};
Many thanks!

"Evaluate" Function that is stored in MongoDB Server

My collection looks like this:
> db.projects_columns.find()
{ "_id" : "5b28866a13311e44a82e4b8d", "checkbox" : true }
{ "_id" : "5b28866a13311e44a82e4b8e", "field" : "_id", "title" : "ID", "sortable" : true }
{ "_id" : "5b28866a13311e44a82e4b8f", "field" : "Project", "title" : "Project", "editable" : { "title" : "Project", "placeholder" : "Project" } }
{ "_id" : "5b28866a13311e44a82e4b90", "field" : "Owner", "title" : "Owner", "editable" : { "title" : "Owner", "placeholder" : "Owner" } }
{ "_id" : "5b28866a13311e44a82e4b91", "field" : "Name #1", "title" : "Name #1", "editable" : { "title" : "Name #1", "placeholder" : "Name #1" } }
{ "_id" : "5b28866a13311e44a82e4b92", "field" : "Name #2", "title" : "Name #2", "editable" : { "title" : "Name #2", "placeholder" : "Name #2" } }
{ "_id" : "5b28866a13311e44a82e4b93", "field" : "Status", "title" : "Status", "editable" : { "title" : "Status", "type" : "select", "source" : [ { "value" : "", "text" : "Not Selected" }, { "value" : "Not Started", "text" : "Not Started" }, { "value" : "WIP", "text" : "WIP" }, { "value" : "Completed", "text" : "Completed" } ], "display" : "function (value, sourceData) { var colors = { 0: 'Gray', 1: '#E67C73', 2: '#F6B86B', 3: '#57BB8A' }; var status_ele = $.grep(sourceData, function(ele){ return ele.value == value; }); $(this).text(status_ele[0].text).css('color', colors[value]); }", "showbuttons" : false } }
You can see that in the very last document that I have stored a function as text.Now the idea is that I will request this data and will be in an Javascript Array format.
But I want to be able to have my function without the quotes! You can see that simply evaluating it will not work because I need to have it still needs to be inside of the object ready to be executed when the array is used.
How can I achieve this?
Thanks for any help!
There are two possible solutions, but neither particularly safe and you should strongly consider why you need to store functions as strings in the first place. That being said, you could do two things.
The simplest is to use eval. To do so, you would have to first parse the object like normal, and then set the property that you want to the result of eval-ing the function string, like so:
// Pass in whatever JSON you want to parse
var myObject = JSON.parse(myJSONString);
// Converts the string to a function
myObject.display = eval("(" + myObject.display + ")");
// Call the function with whatever parameters you want
myObject.display(param1, param2);
The additional parentheses are to make sure that evaluation works correctly. Note, that this is not considered safe by Mozilla and there is an explicit recommendation not to use eval.
The second option is to use the Function constructor. To do so, you would need to restructure your data so that you store the parameters separately, so you could do something like this:
var myObject = JSON.parse(myJSONString);
// displayParam1 and displayParam2 are the stored names of your parameters for the function
myObject.display = Function(myObject.displayParam1, myObject.displayParam2, myObject.display)
This method definitely takes more modification, so if you want to use your existing structure, I recommend eval. However, again, make sure that this is absolutely necessary because both are considered unsafe since outside actors could basically inject code into your server.

Accessing arrays

I'm using the Raphaƫl framework to draw dynamic shapes (which make them clickeable, you can make them glow...).
I can't access the array correctly.
I've created an array :
var siegeurs = {
1 : [{
"Nom" : "User1",
"Photo" : "url"
}],
2 : [{
"Nom" : "User2",
"Photo" : "url"
}],
3 : [{
"Nom" : "User3",
"Photo" : "url"
}],
4 : [{
"Nom" : "User4",
"Photo" : "url"
}],
5 : [{
"Nom" : "User5",
"Photo" : "url"
}]
};
These are the shapes that the framework draw :
sieges["1"] = assembly.path("M236.51 ... 108");
sieges["2"] = assembly.path("M483.51 ... 71");
sieges["3"] = assembly.path("M427.51 ... 272");
sieges["4"] = assembly.path("M135.51 ... 348");
sieges["5"] = assembly.path("M617.51 ... 413");
They are like object so you can interact with them.
This is the loop :
for(var siegeNum in sieges) {
(function (siege) {
siege.attr(style); //apply style to shapes
siege[0].addEventListener("mouseover", function() {
siege.animate(hoverStyle, animationSpeed); //add hoverstyle when hovered
//The line I can't figure out
document.getElementById("textelement").innerHTML = siegeurs[siegeNum]["Nom"];
//The line I can't figure out
}, true);
siege[0].addEventListener("mouseout", function() {
siege.animate(style, animationSpeed);
document.getElementById("textelement").innerHTML = baseTxt;
}, true);
})
(sieges[siegeNum]);
}
textelement is a basic text I try to modify when a shape is hovered.
Actually, when I hover a shape, the text goes to "undefined".
I tried to do this way just to check :
document.getElementById("textelement").innerHTML = siegeurs[siegeNum];
But when I hover, the text goes to [object Object].
Any help is appreciated.
Each value in your siegeurs object is an array, so the needed inner property "Nom" should be accessed as:
...
document.getElementById("textelement").innerHTML = siegeurs[siegeNum][0]["Nom"];

Fetch all data from json and display it on the index page

I have the following json:
[
{
"countryId" : 0,
"countryImg" : "../img/france.jpg",
"countryName" : "France",
"countryInfo" : {
"headOfState" : "Francois Hollande",
"capital" : "Paris",
"population" : 66660000,
"area" : 643801,
"language" : "French"
},
"largestCities" : [
{"Paris" : "../img/paris.jpg"},
{"Marseille" : "../img/marseille.jpg"},
{"Lyon" : "../img/lyon.jpg"}
]
},
{
"countryId" : 1,
"countryImg" : "../img/germany.jpg",
"countryName" : "Germany",
"countryInfo" : {
"headOfState" : "Angela Merkel",
"capital" : "Berlin",
"population" : 81459000,
"area" : 357168,
"language" : "German"
},
"largestCities" : [
{"Berlin" : "../img/berlin.jpg"},
{"Munich" : "../img/munich.jpg"},
{"Hamburg" : "../img/hamburg.jpg"}
]
}
]
I need put it in my index.html, however I don't understand why I get only the second object? I need to put two objects in index. Maybe I need to use a loop? How do I do this properly?
I have the following javascript code:
$.ajax({
method: "POST",
url: "../data/data.json"
}).done(function (data) {
/*console.log(data);*/
localStorage.setItem('jsonData', JSON.stringify(data));
var dataFromLocStor = localStorage.getItem('jsonData');
var dataObject = JSON.parse(dataFromLocStor);
console.log(dataObject);
function Countries(){
this.getCountries = function () {
var ulListElem = document.getElementById("list-of-teams").children,
imgCountry = document.createElement('img');
for(country in dataObject){
/*console.log(dataObject[team]['teamName']);*/
imgCountry.setAttribute('src', dataObject[country]['countryImg']);
imgCountry.setAttribute("width", "400");
imgCountry.setAttribute("height", "300");
console.log(country);
ulListElem[0].innerHTML = dataObject[country]['countryId'];
ulListElem[1].innerHTML = dataObject[country]['countryName'];
ulListElem[2].appendChild(imgCountry);
ulListElem[3].innerHTML = dataObject[country]['countryInfo']['headOfState'];
ulListElem[4].innerHTML = dataObject[country]['countryInfo']['capital'];
ulListElem[5].innerHTML = dataObject[country]['countryInfo']['population'];
ulListElem[6].innerHTML = dataObject[country]['countryInfo']['area'];
ulListElem[7].innerHTML = dataObject[country]['countryInfo']['language'];
}
}
}
var countriesDate = new Countries();
countriesDate.getCountries();
});
You are setting the same UI elements (img and ul) twice inside a loop. When the loop runs first time, the values are set from the first array element. When the loop runs second time, the SAME elements are overwritten with the new values.
To properly display all elemts from the JSON array, you need two sets of UI elements in the index.html page e.g. two imgs, two uls etc.

How to access a part of a JSON file

Im trying to access some data and keep getting errors no matter what I try. Please help.
"rain":{"3h":13.625} is the part of the JSON file I am trying to access.
Here is what I have tried:
var currentRain = data.rain.3h; Which is most logical as it worked before but the number is what is giving the error.
var currentRain = data.rain["3h"];
var currentRain = data.rain[0]["3h"];
var currentRain = data.rain["3h"][0];
UPDATE:
This is the JSON payload:
{ "base" : "stations",
"clouds" : { "all" : 92 },
"cod" : 200,
"coord" : { "lat" : -33.850000000000001,
"lon" : 151.22
},
"dt" : 1429558616,
"id" : 6619279,
"main" : { "grnd_level" : 1024.97,
"humidity" : 100,
"pressure" : 1024.97,
"sea_level" : 1031.0999999999999,
"temp" : 288.77699999999999,
"temp_max" : 288.77699999999999,
"temp_min" : 288.77699999999999
},
"name" : "City of Sydney",
"rain" : { "3h" : 13.625 },
"sys" : { "country" : "AU",
"message" : 0.0101,
"sunrise" : 1429474880,
"sunset" : 1429514809
},
"weather" : [ { "description" : "heavy intensity rain",
"icon" : "10n",
"id" : 502,
"main" : "Rain"
} ],
"wind" : { "deg" : 157.5,
"speed" : 8.3200000000000003
}
}
You'll need to use ["bracket notation"] to access this, since "3h" begins with a number. As MDN explains:
An object property name can be any valid JavaScript string, or anything that can be converted to a string, including the empty string. However, any property name that is not a valid JavaScript identifier (for example, a property name that has a space or a hyphen, or that starts with a number) can only be accessed using the square bracket notation.
This is the correct JSON:
{
"rain": {
"3h": 13.625
}
}
First you need to parse it and transform into an object:
var jsonToObject = JSON.parse('{"rain":{"3h":13.625}}');
You can now access it like this:
jsonToObject.rain["3h"]
Just use data["rain"]. If you need to parse it first do JSON.parse(data) and then data["rain"].
OUTPUT
console.log(data["rain"]);
> { '3h': 13.625 }
...keep in mind that will return an Object.

Categories

Resources