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 Handle Multiple Promises with Promise.all

Peter Glover
Peter Glover
8,582 Points

Handling 404 Status from Wikipedia

The instructor's solution breaks when there is a spelling mismatch in the person's name in the astros.json query results and their Wikipedia entry. This seems to happen particularly for the residents of the Chinese Tiangong space station, Even one 404 status from the Wikipedia queries cause the Promise.all(profiles) in getProfiles(json) to reject in its entirety

Here's my solution to the problem.

First, add the flag allow404 to the getJSON parameter list. When allow404 == true, do not reject 404 statuses.

function getJSON(url, allow404 = false) {
  //when allow404 == true, http 404 errors won't reject Promise
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.onload = () => {
      if (xhr.status === 200 || (xhr.status === 404 && allow404)) {
        let data = JSON.parse(xhr.responseText);
        resolve(data);
      } else {
        reject(Error(xhr.statusText));
      }
    }
    xhr.onerror = () => reject(Error('A network error occured.'));
    xhr.send();
  });
}

Next, in getProfiles(json) pass allow404 = true for all the Wikipedia biography queries.

function getProfiles(json) {
  const profiles = json.people.map(person => {
    return getJSON(wikiUrl + person.name, true);
  });
  return Promise.all(profiles);
}

Lastly, add handling in generateHTML(data) for each person whose biography was not found on Wikipedia. I added a Google search link for the person's name.

function generateHTML(data) {
  data.map(person => {
    const section = document.createElement('section');
    peopleList.appendChild(section);
    if (person.title === 'Not found.') {
      /*If Bio page wasn't found, pull person's name out of URL and format a 
      section with defaults
      */
      let uriToTokens = person.uri.split('/');
      let name = decodeURI(uriToTokens[uriToTokens.length - 1]);
      section.innerHTML = `
     <img src="img/profile.jpg" alt="ocean clouds seen from space">
     <h2>${name}</h2>
     <p>Wikipedia results unavailable for ${name}</p>
     <p>But this person is really in space! Try searching 
     <a href="https://www.google.com/search?q=${encodeURIComponent(name)}" target="_blank">Google for them</a></p>
   `;
    } else if (person.type === 'standard') {
      // Check if request returns a 'standard' page from Wiki
      section.innerHTML = `
        <img src=${person.thumbnail.source}>
        <h2>${person.title}</h2>
        <p>${person.description}</p>
        <p>${person.extract}</p>
      `;
    } else {
      section.innerHTML = `
        <img src="img/profile.jpg" alt="ocean clouds seen from space">
        <h2>${person.title}</h2>
        <p>Results unavailable for ${person.title}</p>
        ${person.extract_html}
      `;
    }
  });
}

The instructor's solution also does not handle Wikipedia disambiguation pages well, but since that does not actually break the project page, I did not fix it.

Great solution! thank you for posting.

1 Answer

Steven Parker
Steven Parker
229,757 Points

A few folks have also posted solutions for this issue, you might check out the answers to similar questions.

Handling disambiguation issues might not be too hard either, particularly since only one entry is likely to have a keyword indicating an astronaut on the line.   :wink:

Peter Glover
Peter Glover
8,582 Points

Yep, there's a few other alternatives to my solution. There is also at least one disambiguation solution too (it does have to handle "astronaut", "cosmonaut" or "taikonauts" next to the name on the disambiguation line).