Problem
I am just starting with JavaScript and jQuery, so I appreciate your help!
I want to read items from a JSON file like this:
{
"items": [
"this",
"that"
]
}
My code (inspired by a number of stackoverflow and jQuery reference example code) looks like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
</head>
<body>
<div id="notification"></div>
<ul id="items"></ul>
<script>
$.get('list.json', {}, function(data, response){
var jsonResult;
try {
jsonResult = JSON.parse(data);
}
catch (e) {
$('div#result').html('<span style="color:red">cannot load data because: "'+e+'"</span>');
};
var items = []
$.each( jsonResult['items'], function( key, val ) {
items.push( "<li id='item-" + key + "'>" + val + "</li>" );
});
/* // this does not work
$( "<ul/>", {
"class": "my-new-list",
html: items.join( "" )
}).appendTo( "div#notification" );
*/
$('ul#items').html(items.join(""));
});
</script>
</body>
</html>
And it works. Yay.
My questions:
- Is that more or less ok what I nitted? What can be enhanced?
- Why does the commented-out section not work? I took this from https://api.jquery.com/jQuery.getJSON/
Solution
Some ideas:
#1
– I suggest using .map().join()
or even better .reduce()
which is more semantically correct for what you want to do: reduce a array to an html string.
#2
– You should also use var jsonResult = {items: []};
otherwise if the catch
gets called you will have a error down the line because you expect jsonResult
to be an Object.
#3
– Another thing: I suppose your example is simplified so much it became incorrect, since the items
array has strings, and not objects with key
and val
…
{
"items": [
"this",
"that"
]
}
#4
– You did have an error in your code, you were using function( key, val ) {
, but that is not the jQuery API. The callback gets the iterated item as this
and in the second argument. The first argument is the index
…
You could use a callback with destructuring like this:
var items = []
$.each(jsonResult['items'], function(i, {key, val}){
items.push( "<li id='item-" + key + "'>" + val + "</li>" );
});
Improved code suggestion:
$.get('list.json', {}, function(data, response) {
var jsonResult = {items: []};
try {
jsonResult = JSON.parse(data);
} catch (e) {
$('div#result').html('<span style="color:red">cannot load data because: "' + e + '"</span>');
};
var html = jsonResult['items'].reduce(function(string, item) {
return string + "<li id='item-" + item.key + "'>" + item.val + "</li>"
}, '');
$('ul#items').html(html);
});
#5
– About your commented code question:
You are trying to use .join()
on objects. It does work if you fix what I suggested above(jsFiddle).