Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript Asynchronous Programming with JavaScript Asynchronous JavaScript with Callbacks Implement a Callback

charlie g
charlie g
12,417 Points

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

Hey guys, I'm getting the following error when I try and run my code:

Uncaught TypeError: Cannot read property 'source' of undefined at generateHTML (callbacks.js:25) at XMLHttpRequest.xhr.onload (callbacks.js:14)

Thank you.

this error happens when the object is undefined. Be sure to paste the code or else we can't help you. Also be sure to format it.

Remi Vledder
Remi Vledder
14,144 Points

Facing the same problem. Do you also have some empty sections on the page as well?

I think this all has to do with timing of the asynchronous part of the code. Perhaps at a later stage in this course this will be addressed?

charlie g
charlie g
12,417 Points

Yes Remi! The problem is with these two names Alexander Skvortsov and Andrew Morgan, could be referred to by the same search term? I mean there is more than one Alexander Skvortsov and Andrew Morgan.

the issue is not the string value but that the client(the browser) is fetching the data slower than it can render the content, so source undefined means that data.thumbnail still does not exist yet. It's running synchronous compared to asynchronous

2 Answers

the reason you're getting this message is because the first time data.thumbnail.source on the img tag is rendered, it's still getting fetched from the url hence it it undefined for that split second, and by the time the img gets rendered the err on the console is already spit out. So what you can do is check first to see if the data IS NOT undefined then go ahead and build out the ui like so

function generateHTML(data) {
  const section = document.createElement('section');
  peopleList.appendChild(section);
  if (data.thumbnail != undefined) { // check to see if data is undefined
    section.innerHTML = `
    <img src=${data.thumbnail.source}>
    <h2>${data.title}</h2>
    <p>${data.description}</p>
    <p>${data.extract}</p>
  `;
  }
}

or i would just add this. This just adds the if conditional directly to the string literal

    <img src=${data.thumbnail != undefined ? data.thumbnail.source : ""}>
Remi Vledder
Remi Vledder
14,144 Points

Both examples assume the thumbnail is present and is an anti-pattern.

In the first example the entire block wouldn't load if the thumbnail isn't present. In the second example with the ternary operator an image tag with an empty "src" attribute will be added to the page.

Perhaps this is a solution:

${data.thumbnail ? '<img src="'+data.thumbnail.source+'" />' : '' }
Gabbie Metheny
Gabbie Metheny
33,778 Points

Remi Vledder is right that you'll run into problems when the data doesn't return an image (data.thumbnail.source), and charlie g is correct that there is more than one Aleksandr Skvortsov and Andrew Morgan. If you log out the data to the console, you can see that the type of page (data.type) returned for both of them is disambiguation, which is the type of page Wikipedia gives you when there's more than one possibility for a search term. For a more positive user experience, you could build on Remi's ternary operator solution and return the image if the page is standard type and the link to the Wikipedia disambiguation page if the type is disambiguation (an if/else statement would also work).

function generateHTML(data) {
  const section = document.createElement('section');
  peopleList.appendChild(section);
  // use the ternary operator
  // to add the image to the page
  // or a link to the Wikipedia disambiguation page
  section.innerHTML = `
    ${data.type === 'standard' ? 
      `<img src=${data.thumbnail.source}>` :
      `<a href=${data.content_urls.desktop.page}>Wikipedia disambiguation page</a>`}
    <h2>${data.title}</h2>
    <p>${data.description}</p>
    <p>${data.extract}</p>
  `;
}
Julianna Kahn
Julianna Kahn
20,702 Points

What a great fix, thank you!

Very nice, thank you for sharing!