2

I know there's already a million questions about this, but I cannot find the answer. All I want to do is iterate over a JSON array (and the object) and print out all its values using jQuery's .each() method.

{
    "items": [{
        "new_active_users": 3,
        "total_users": 179757,
        "badges_per_minute": 0.05,
        "total_badges": 318126,
        "total_votes": 720066,
        "total_comments": 346593,
        "answers_per_minute": 0.02,
        "questions_per_minute": 0.01,
        "total_answers": 97538,
        "total_accepted": 35924,
        "total_unanswered": 6162,
        "total_questions": 61943,
        "api_revision": "2019.8.29.34367"
    }],
    "has_more": false,
    "quota_max": 300,
    "quota_remaining": 299
}

I've hardly worked with JSON and the examples I can find do not explain how to iterate over an array within an array using the jQuery's .each() method. I can find tons of examples of simple arrays, but none that are quite structured this way. I'm just struggling to wrap my head around what I'm doing wrong.

Right now I've managed to print out some of the array but I cannot figure out how to access the array within "items".

Get Request

// JavaScript Document
$(function(){
    $("#get-info").click(function(){
        var $text = $(".post-text");
        $.getJSON("/json/se-codereview-info.txt", function(data){
            $.each(data, function(key, val){
                $text.append(key + ":" + val + "<br>");
            });
        });
    });
});

Response

items:[object Object]
has_more:false
quota_max:300
quota_remaining:299

I have tried several different ways of trying to access items but nothing is working for me. Using key.items or key["items"] within the first .each() method or using data.items or data["items"] outside the first .each() method, I tried removing the loop all together and started trying to get any value in items, but I'm struggling to do so. I tried tons of different ways, and I'm at the point where I just don't understand anymore. I'm trying to be consistent and I thought I could just access the internal array with what I have below.

Get Request V2

// JavaScript Document
$(function(){
    $("#get-info").click(function(){
        var $text = $(".post-text");
        $.getJSON("/json/se-codereview-info.txt", function(data){
            $.each(data, function(key, val){
                $.each(val["items"], function(key_i, val_i){
                    $text.append(key_i + ":" + val_i + "<br>");
                });
            });
        });
    });
});

I'd appreciate any help or an explanation of what I'm doing wrong or a link to the post I've been looking for, for the past 2 days.

These are some of the pages I've already visited, and do not explain how to solve this.

sBucholtz
  • 74
  • 10

3 Answers3

0

Here is how you can iterate all the way down without jQuery which isn’t required for this kind of iteration.

<html lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> -->
    <script>
      // $(function() {
      // });
      // Convert to JSON to make sure everything works
      var json = JSON.stringify({
        'items': [
          {
            'new_active_users': 3,
            'total_users': 179757,
            'badges_per_minute': 0.05,
            'total_badges': 318126,
            'total_votes': 720066,
            'total_comments': 346593,
            'answers_per_minute': 0.02,
            'questions_per_minute': 0.01,
            'total_answers': 97538,
            'total_accepted': 35924,
            'total_unanswered': 6162,
            'total_questions': 61943,
            'api_revision': '2019.8.29.34367'
          }
        ],
        'has_more': false,
        'quota_max': 300,
        'quota_remaining': 299
      });
      // Convert back to object
      var object = JSON.parse(json);
      // Iterate through object properties
      for (var property in object){
        var value = object[property];
        console.log(property, value);
        // If property is item, iterate through array
        if (property === 'items') {
          value.forEach(function(item) {
            // Iterate through item properties
            for (var _property in item){
              var _value = item[_property];
              console.log(_property, _value);
            }
          });
        }
      }
    </script>
  </head>
  <body>
  </body>
</html>
sunknudsen
  • 6,356
  • 3
  • 39
  • 76
0

A bit of advice for when you're dealing with understanding the data you have in a JavaScript script, is to use console.log(variable).

For example, console.log(data.items) would output this to your developer's console.

{
        "new_active_users": 3,
        "total_users": 179757,
        "badges_per_minute": 0.05,
        "total_badges": 318126,
        "total_votes": 720066,
        "total_comments": 346593,
        "answers_per_minute": 0.02,
        "questions_per_minute": 0.01,
        "total_answers": 97538,
        "total_accepted": 35924,
        "total_unanswered": 6162,
        "total_questions": 61943,
        "api_revision": "2019.8.29.34367"
}

This is the structure that data.items follows, being an object composed of keys (e.g new_active users, api_revision etc.) and values (e.g 3, 2019.8.29.34367 respectively).

Hence, to access each key and value, we do, using JQuery,

// JavaScript Document
$(function(){
    $("#get-info").click(function(){
        var $text = $(".post-text");
        $.getJSON("/json/se-codereview-info.txt", function(data) {
            $.each(data.items, function(key, val){
                $text.append(key + ":" + val + "<br>");
            });
        });
    });
});
HilliamT
  • 96
  • 4
0

Using your example I made a general purpose function objectToHTML() to recursively convert an object into an HTML string. The function loops through any object, if any object attribute is either an array or a plain object then it will process it with the same function while passing a prefix to notate the parent object been processed.

Review the code below:

function objectToHTML(data, prefix) {
  var output = '';
  // Default prefix to empty string
  prefix = prefix || '';
  
  $.each(data, function(key, val) {
    if ($.isArray(val) || $.isPlainObject(val)) {
      // process the val item with the same function
      output += objectToHTML(val, prefix + key + '.');
    } else {
      output += prefix || '';
      output += key + ": " + val + "<br>"
    }
  });

  return output;
}

var dataObj = {
  "items": [{
    "new_active_users": 3,
    "total_users": 179757,
    "badges_per_minute": 0.05,
    "total_badges": 318126,
    "total_votes": 720066,
    "total_comments": 346593,
    "answers_per_minute": 0.02,
    "questions_per_minute": 0.01,
    "total_answers": 97538,
    "total_accepted": 35924,
    "total_unanswered": 6162,
    "total_questions": 61943,
    "api_revision": "2019.8.29.34367"
  }],
  "has_more": false,
  "quota_max": 300,
  "quota_remaining": 299
}

$('body').append(objectToHTML(dataObj))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Pablo
  • 5,897
  • 7
  • 34
  • 51