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:

up vote 5 down vote accepted

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).

  • thank you. one question: Can't I have an array of simple strings in the json file? The key (in my code) becomes indices then. – steffen Aug 25 '17 at 12:52
  • jQuery also has a getJSON method that avoids the need to constantly write a try-catch block. api.jquery.com/jQuery.getJSON – Andrea Lazzarotto Aug 25 '17 at 13:17
  • @steffen you can have just strings in you JSON. In that case you can use function( key, val ) { where key is the numeric index. – Sergio Aug 25 '17 at 13:29
  • @AndreaLazzarotto true. And I think the OPs question has code from those docs. – Sergio Aug 25 '17 at 13:30

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.