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 Understanding Promises Using Fetch

benjaminmosery
benjaminmosery
6,346 Points

Code not running properly

My code, when previewed in Workspaces, is not running. The button, when pressed, states that something is wrong and I get the following error:

TypeError: "json.people is undefined"
    getProfiles http://port-80-hwjr5vh1mn.treehouse-app.com/js/promises.js:7
                                                                                                                promises.js:35:17

Here is my code currently:

const astrosUrl = 'http://api.open-notify.org/astros.json';
const wikiUrl = 'https://en.wikipedia.org/api/rest_v1/page/summary/';
const peopleList = document.getElementById('people');
const btn = document.querySelector('button');

function getProfiles(json) {
  const profiles = json.people.map( person => {
   return fetch(wikiUrl + person.name, generateHTML)
   .then(response => response.json())
  }); 
  return Promise.all(profiles);
}

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

btn.addEventListener('click', (event) => {
  event.target.textContent = "Loading…";

  fetch(astrosUrl)
  .then(getProfiles)
  .then(response => response.json())
  .then(generateHTML)
  .catch(err => {peopleList.innerHTML = '<h3>Something went wrong!</h3>';
        console.log(err)
   })
  .finally(() =>event.target.remove())
});

I do not see why there is an error in line 35 indicating that "json.people" is undefined if this is how Guil wrote it in the video. Any guidance on how to resolve the issue would be appreciated.

6 Answers

One solution from a previous post

function generateHTML(data) {
  data.map(person => {
    const section = document.createElement('section');
    peopleList.appendChild(section);
    if (person.type === "standard") {
      section.innerHTML = `
      <img src=${person.thumbnail.source}>
      <h2>${person.title}</h2>
      <p>${person.description}</p>
      <p>${person.extract}</p>`;
    } else {
      section.innerHTML = `
      <h2>${person.title}</h2>
      <p>No description available</p>`;
    }
  })
}

If you watch the video @1:47 you'll see the order of these two lines is reversed

 .then(getProfiles)
 .then(response => response.json())

in btn.addEventListener. Fixing this however leads to a new error.

benjaminmosery
benjaminmosery
6,346 Points

Kris,

I did as requested and still get the following error:

TypeError: "person.thumbnail is undefined"
    generateHTML http://port-80-hwjr5vh1mn.treehouse-app.com/js/promises.js:19
    generateHTML http://port-80-hwjr5vh1mn.treehouse-app.com/js/promises.js:15
promises.js:34:25

According to my console's debugger, the problem is with the generateHTML function, specifically the "person" argument in data.map and the image source for the thumbnail as person.thumbnail.source:

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

This doesnt make much sense as it looks the same as the code in Guil's video. Any advice would be appreciated.

Hey I'm getting the same error, even when using the final supplied code it keeps returning 'Cannot read property 'source' of undefined'

Joshua - Can you post your code? You may need to start a new topic. By final supplied code do you mean downloaded project files?

Hi, looking on the slack channels it seems to be a known bug, I think because the API has been modified so it keeps throwing that error. The final downloaded code available is the one throwing errors.

KRIS NIKOLAISEN Joshua Fielding benjaminmosery It looks like it's a known issue, thanks fairest for the heads up. Very frustrating, because the last 3 videos haven't worked for me in this course. At first I thought it was my code, but even with the 'final' code contained in the Project FIles it doesn't work.

Not all astronaut wiki entries contain a thumbnail or an excerpt. This throws off the code. Would be better to create an example based on historic figures, not every new astronaut already has a wiki entry let alone a complete wiki entry.

const astrosUrl = 'http://api.open-notify.org/astros.json'; const wikiUrl = 'https://en.wikipedia.org/api/rest_v1/page/summary/'; const peopleList = document.getElementById('people'); const btn = document.querySelector('button');

function getProfiles(json) { const profiles = json.people.map( person => { const craft = person.craft; return fetch(wikiUrl + person.name) .then(response => response.json()) .then( profile => { return {...profile, craft}; }) .catch ( err => console.log('Error fetching Wiki', err)) }); return Promise.all(profiles); }

// Generate the markup for each profile

function generateHTML(data) { data.map(person => { const section = document.createElement('section'); peopleList.appendChild(section); if (person.type === "standard") { section.innerHTML = <img src=${person.thumbnail.source}> <h2>${person.title}</h2> <p>${person.description}</p> <p>${person.extract}</p>; } else { section.innerHTML = <h2>${person.title}</h2> <p>No description available</p>; } }) }

btn.addEventListener('click', (event) => { event.target.textContent = 'Loading';

fetch(astrosUrl) .then(response => response.json()) .then(getProfiles) .then(generateHTML) .catch (err => { peopleList.innerHTML = '<h3>Something went wrong</h3>'; console.log(err) }) .finally( () => event.target.remove() ) });

My code is not working either