1

I have a JSON have the following data:

        {
       "results":[
          {
             "name":"Sydney Showboats",
             "photos":[
                {
                   "photo_reference":"Pic062"
                }
             ]
          },
          {
             "name":"Blue Line Cruises"
          },
          {
             "name":"Rhythmboat Cruises",
             "photos":[
                {
                   "photo_reference":"Pic678"
                }
             ]
          },
          {
             "name":"Flying Fish Restaurant & Bar",
             "photos":[
                {
                   "photo_reference":"Pic345"
                }
             ]
          }
       ],
       "status":"OK"
    }

I'm trying to loop through this JSON to display every name value in the .name div and every image in the .photo div:

$.getJSON(jsonPlacesUrl, function(data) {
  $.each(data.results, function(index){
    $('.name').html('<p>' + data.results[index].name + '</p>');
    $('.photo').html('<img src="' + data.results[index].photos[0].photo_reference + '.jpg">');
  })
});

It works fine with the name value and works fine with the first image too. However, since there is no "photos" property in the second object, the script stops because of an

Uncaught TypeError: Cannot read property '0' of undefined.

So is there a way to either: Delete the objects which do not have the photos object nested inside? Use a more complex loop to iterate through the JSON and store every image available? Any possible solution allowing me to display every image available dynamically?

If anyone can enlighten me it would be gratefully appreciated!

0

2 Answers 2

3

You want to make sure that the current object in the iteration contains that property. One way to check if an object contains a property is using the in operator.

$.getJSON(jsonPlacesUrl, function(data) {
  $.each(data.results, function(index){
    if ('photos' in data.results[index] && 'name' in data.results[index]){
      $('.name').html('<p>' + data.results[index].name + '</p>');
      $('.photo').html('<img src="' + 
      data.results[index].photos[0].photo_reference + '.jpg">');
    }
 })

});

Documentation for in operator

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

4 Comments

This doesn't deserve a random downvote any more than mine does, it's a perfectly reasonable solution. +1 :)
Both are good solutions to this problem. I'm not sure why they were down voted @msanford .
Someone had a bad day. Whatever. Note that there is also an accessor on name so you might want to add that guard as well, just for completeness.
Edited and added check for the other property. @Stephan great! :)
1

Any time you have an "Uncaught TypeError: Cannot read property 'prop-name' of undefined" you have a situation in which you need to add a guard against undefined:

$.getJSON(jsonPlacesUrl, function(data) {
  $.each(data.results, function(index){
    if (typeof data.results[index].photos !== "undefined" && typeof data.results[index].name !== "undefined") { // <- Here
      $('.name').html('<p>' + data.results[index].name + '</p>');
      $('.photo').html('<img src="' + data.results[index].photos[0].photo_reference + '.jpg">');
    }
  })
});

If you need to ensure that ancestors are defined, it can be chained, like:

if (typeof a !== "undefined" && typeof a.b !== "undefined" && typeof a.b.c !== "undefined")

and so on.

Also note Pablo's answer featuring in which is more concise.

Alternatively, you can filter your list:

const json_parsed = {
  "results": [{
      "name": "Sydney Showboats",
      "photos": [{
        "photo_reference": "Pic062"
      }]
    },
    {
      "name": "Blue Line Cruises"
    },
    {
      "name": "Rhythmboat Cruises",
      "photos": [{
        "photo_reference": "Pic678"
      }]
    },
    {
      "name": "Flying Fish Restaurant & Bar",
      "photos": [{
        "photo_reference": "Pic345"
      }]
    }
  ],
  "status": "OK"
}

clean_list = json_parsed['results'].filter(item => typeof item.photos !== "undefined" && typeof item.name !== "undefined");

console.dir(clean_list);

1 Comment

Thank you very much for this very complete answer, this is really helpful since I struggled a lot on this issue!

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.