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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.