3

I need to take a JSON object and get the titles console logged for an auto complete feature. AN example of what my json looks like is below:

[
  {
    "title": "Example 1",
    "url": "http:\/\/www.example1.com\/"
  },
  {
    "title": "Example 2",
    "url": "http:\/\/www.example2.com\/"
  },
  {
    "title": "Example 3",
    "url": "http:\/\/www.example3.com\/"
  }, ...

I would like to log all the titles in my console like this:

Example 1
Example 2
Example 3

My initial attempt to do what I want was this:

$.ajax({
      type: "GET",
      dataType: 'json',
      url: "/url/to/json/",
      success: function(data) {
        var searchResults = JSON.parse(data);
        console.log(searchResults.title);
      },
    });

This returned:

Unexpected token o in JSON at position 1

After some further research:

Unexpected token o in JSON at position 1

SyntaxError: Unexpected token o in JSON at position 1

What is causing “Uncaught SyntaxError: Unexpected token o” with $.parseJSON() and JSON.parse()

It is suggested that the data is already parsed. So I try to call the object directly as these answers suggest:

$.ajax({
      type: "GET",
      dataType: 'json',
      url: "/url/to/json/",
      success: function(data) {
        console.log(data.title);
      },
    });

This gives me:

undefined

How do I print specific JSON data in console, in this case - title? If data is already parsed then how come when I try to access it it returns undefined?

kawnah
  • 3,204
  • 8
  • 53
  • 103

2 Answers2

5

If your data has the format:

[
  {
    "title": "Example 1",
    "url": "http:\/\/www.example1.com\/"
  },
  {
    "title": "Example 2",
    "url": "http:\/\/www.example2.com\/"
  },
...

To print each title/url, you need to iterate through the result (using a for or calling forEach as below):

$.ajax({
  type: "GET",
  dataType: 'json',
  url: "https://api.myjson.com/bins/1czpnp",
  success: function(data) {
    console.log(data.title); // undefined
    console.log(data); // the [{...}] object

    // to print the title/urls, iterate over the array
    // alternative 1 (ordinary for):
    for(var i = 0; i < data.length; i++) {
      var d = data[i];
      console.log('title: ' + d.title + ' ~ url: ' + d.url);
    };

    // alternative 2 (forEach):
    data.forEach(function (d) {
      console.log('title: ' + d.title + ' ~ url: ' + d.url);
    });
  },
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Comments questions

console.log(data.title); is undefined because we are not looping through it, right?

Kind of. It is undefined because data is an array. And JavaScript arrays don't have a title property.

in the line data.forEach(function (d) { , what exactly is (d)? Where is that value coming from? What does it represent?

.forEach is a method present in JavaScript arrays. It takes a function as argument and then calls that function on each element of the array.

Example:

var myArray = [1, 2, 3];
myArray.forEach(function (number) { console.log(number); });

Will print in the console:

1
2
3

Which is the result of calling function (number) { console.log(number); } three times (one for each element of the myArray array), where the first number value will be 1, the second time it will be 2 and the last time it will be 3.

And why does the vanilla JS loop not pass in (d)

A for is a mere execution of a given statement a given number of times. It does not pass d because there is no function argument involved (as it happens with .forEach).

In other words, a for is:

for(var i = 0; i < n; i++) {
  // execute whatever is here "n" times, each time having "i" being a different value
}

So when we do

for(var i = 0; i < data.length; i++) {
  // some command
}

We are asking to execute some command data.length times. data.length is a number that means the length of the data array. (e.g. ['a','b'].length is 2).

Since it just executes a command, we have to "create" the d ourselves each time, thus: var d = data[i]; to get each data element.

acdcjunior
  • 132,397
  • 37
  • 331
  • 304
  • `console.log(data.title);` is undefined because we are not looping through it, right? in the line `data.forEach(function (d) {` , what exactly is `(d)`? Where is that value coming from? What does it represent? – kawnah Feb 28 '18 at 15:51
  • And why does the vanilla JS loop not pass in `(d)`? – kawnah Feb 28 '18 at 15:54
  • FYI I'm going to accept your answer I just need a better understanding of some of the details – kawnah Feb 28 '18 at 15:55
  • There you go, let me know if it helps. – acdcjunior Feb 28 '18 at 16:08
1

A nested data structure is an array or object which refers to other arrays or objects, i.e. its values are arrays or objects. Such structures can be accessed by consecutively applying dot or bracket notation.

Here is an example:

const data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

Let's assume we want to access the name of the second item.

Here is how we can do it step-by-step:

As we can see data is an object, hence we can access its properties using dot notation. The items property is accessed as follows:

data.items

The value is an array, to access its second element, we have to use bracket notation:

data.items[1]

This value is an object and we use dot notation again to access the name property. So we eventually get:

const item_name = data.items[1].name;

Alternatively, we could have used bracket notation for any of the properties, especially if the name contained characters that would have made it invalid for dot notation usage:

const item_name = data['items'][1]['name'];

To iterate over all elements of the data.items array, we use a for loop:

for(let i = 0, l = data.items.length; i < l; i++) {
    // `i` will take on the values `0`, `1`, `2`,..., i.e. in each iteration
    // we can access the next element in the array with `data.items[i]`, example:
    // 
    // var obj = data.items[i];
    // 
    // Since each element is an object (in our example),
    // we can now access the objects properties with `obj.id` and `obj.name`. 
    // We could also use `data.items[i].id`.
}

One could also use for...in to iterate over arrays, but there are reasons why this should be avoided: Why is 'for(var item in list)' with arrays considered bad practice in JavaScript?.

L Y E S - C H I O U K H
  • 4,765
  • 8
  • 40
  • 57