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?

8
  • 2
    Looks to me as it is returned as an array of objects, just iterate your data, so for(let x = 0; x < data.length; x++){ console.log(data[x].title); } Commented Feb 28, 2018 at 15:40
  • console.log(data) ? Commented Feb 28, 2018 at 15:40
  • Did you try to print arguments of the function in the success? this will provide you a bit more information Commented Feb 28, 2018 at 15:40
  • Use dataType: "text" to skip the json parsing, this will allow you to log the raw response data. Alternatively just use the browser debugging tools to intercept the network request and see the the raw response. Commented Feb 28, 2018 at 15:40
  • 1
    I can't be undefined and have data when stringified... Commented Feb 28, 2018 at 15:43

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

4 Comments

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?
And why does the vanilla JS loop not pass in (d)?
FYI I'm going to accept your answer I just need a better understanding of some of the details
There you go, let me know if it helps.
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?.

Comments