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

Same code and still getting an error

Hi, I am getting this error in the console:

Uncaught TypeError: Cannot read property 'source' of undefined at generateHTML

I don't understand why it can't read data.thumbnail.source

Here is my code:

// Generate the markup for each profile
function generateHTML(data) {
  const section = document.createElement('section');
  peopleList.appendChild(section);
  section.innerHTML = `
    <img src=${data.thumbnail.source}>
    <h2>${data.title}</h2>
    <p>${data.description}</p>
    <p>${data.extract}</p>
  `;
}

btn.addEventListener('click', (event) =>{
    getJSON(astrosUrl, (json) => {
        json.people.map( person => {
            getJSON(wikiUrl + person.name, generateHTML);
        });
    });
    event.target.remove();
});

Someone has also asked the same question but its answer didn't work. Would really appreciate any help.

6 Answers

Cameron Childres
Cameron Childres
11,820 Points

Hey Zaid,

The code as written in this lesson assumes that astronauts' names will return their specific page. It doesn't account for Wikipedia having multiple people of the same name (leading to disambiguation pages) or alternate spellings of names (leading to redirect pages). Both of these situations return data that does not have an associated thumbnail. If there's no thumbnail property then trying to access the source property of thumbnail will give an error. You can see this for yourself by adding a console.log(data) statement to generateHTML() and viewing the properties of the objects produced.

Here's a decent workaround -- replace the section.innerHTML statement with this:

    if (person.thumbnail) { 
      section.innerHTML = `<img src=${person.thumbnail.source}>` ; 
    } 
    section.innerHTML +=  `
      <span>${person.craft}</span>
      <h2>${person.title}</h2>
      <p>${person.description}</p>
      <p>${person.extract}</p>
    `;

This way the code only looks for the image source if the thumbnail property is defined. There's plenty of other ways the code can be cleaned up (disambiguation pages and redirects will produce weird entries) but this will work well enough for the goals of the lesson.

Could you try out this workaround and see if it works for you? Let me know if you have any questions.

Hi Cameron,

Thank you for replying.

This was very helpful.

I went again to my code and added

const img_src = (data.thumbnail && data.thumbnail.source) ? data.thumbnail.source : "";
section.innerHTML = `<img src=${img_src}>`

with double quotes this time and it worked, Although I can only view 4 out of 7 astronauts images because of disambiguation.

Cameron Childres
Cameron Childres
11,820 Points

Great to hear! I think that's the best solution for the purposes of this course. I'm curious about a way to correct for disambiguation pages and redirects but that's a bit outside of the scope for the lesson.

I did it this way, so that at least the name is displayed.

// Generate the markup for each profile
function generateHTML(data) {
  const section = document.createElement('section');
  peopleList.appendChild(section);
  if ( data.type === 'standard' ) {
    section.innerHTML = `
      <img src=${data.thumbnail.source}>
      <h2>${data.title}</h2>
      <p>${data.description}</p>
      <p>${data.extract}</p>
    `;
  } else {
    section.innerHTML = `
      <h2>${data.title}</h2>
    `;
  }
}

Yeah, For sure I am going to dig deeper into this hitch too.

Nick Huemmer
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Nick Huemmer
Front End Web Development Techdegree Graduate 26,840 Points

I ran into the same issue - I had empty sections without any images or text. I pasted in the code that Zaid linked to and got all the Wiki info for each astronaut, but no thumbnail for three of them (Sergey Ryzhikov, Victor Glover or Michael Hopkins). I also received disambiguation messages for each of the astronauts without thumbnails.

Yeah, Nick, I think everyone is going to run into this issue until this gets fixed somehow and, I guess these kinds of issues could be expected when working with APIs.

Nicolle Romero
Nicolle Romero
1,785 Points

I made the following change to just bypass generating HTML for data with type 'disambiguation':

// Generate the markup for each profile
function generateHTML(data) {
  if(data.type === 'disambiguation') {
    return
  }
  const section = document.createElement('section');
  peopleList.appendChild(section);
  section.innerHTML = `
    <img src=${data.thumbnail.source}>
    <h2>${data.title}</h2>
    <p>${data.description}</p>
    <p>${data.extract}</p>
  `;
}

I could not find a solution yet, but is there perhaps a method with which one could filter the returned data for a specific keyword? Like filtering the search on wikipedia for text that contains the words "cosmonaut" || "astronaut" ?