3
\$\begingroup\$

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:

\$\endgroup\$

1 Answer 1

6
\$\begingroup\$

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

\$\endgroup\$
4
  • \$\begingroup\$ 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. \$\endgroup\$
    – steffen
    Commented Aug 25, 2017 at 12:52
  • \$\begingroup\$ jQuery also has a getJSON method that avoids the need to constantly write a try-catch block. api.jquery.com/jQuery.getJSON \$\endgroup\$ Commented Aug 25, 2017 at 13:17
  • \$\begingroup\$ @steffen you can have just strings in you JSON. In that case you can use function( key, val ) { where key is the numeric index. \$\endgroup\$
    – Sergio
    Commented Aug 25, 2017 at 13:29
  • \$\begingroup\$ @AndreaLazzarotto true. And I think the OPs question has code from those docs. \$\endgroup\$
    – Sergio
    Commented Aug 25, 2017 at 13:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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