JavaScript Asynchronous Programming with JavaScript Understanding Promises Handle Multiple Promises with Promise.all

6 Answers

If you just want to know the cause it is because there is ambiguity with two of the names in astros.json: Alexander Skvortsov and Andrew Morgan. You can see this by searching Wikipedia for these names. Changing them to Aleksandr_Skvortsov_(cosmonaut) and Andrew_R._Morgan respectively will load the correct pages. How you go about doing that is up to you.

One means is to modify getProfiles

function getProfiles(json) {
   const profiles = json.people.map(person => {

   if (person.name == "Alexander Skvortsov") {
       person.name = "Aleksandr_Skvortsov_(cosmonaut)"
   }

   if (person.name == "Andrew Morgan") {
       person.name = "Andrew_R._Morgan"
   }

   return getJSON(wikiUrl + person.name);
  });
  return Promise.all(profiles);
}

You could also create your own json file with the edited names and use that instead.

Fabricio Kawata
Fabricio Kawata
8,419 Points

Thank you KRIS, you helped me a lot with your tip!

This is a hack. Treehouse should update this module to include basic data validation. As it stands, the "correct" code is unable to deal with the most rudimentary of errors.

In general, there is a clear lack of focus on programming fundamentals, including thinking through the range of possible inputs, handling edge cases, and thoughtfully composing programs that work in all circumstances. At the moment it's a bit "here's code, change this, do that, it 'works'! Great job!", and I just don't think that's good enough.

Bobby Verlaan
Bobby Verlaan
29,363 Points

Thanks Kris! Pretty hardcoded, but the only way to fix the mappings between the response of the astros.json we get and the Wikipedia API. Meanwhile, the astronauts changed on the ISS, so below the fix that works today:

function getProfiles(json) {
  const profiles = json.people.map( person => {

    if ( person.name === "Andrew Morgan" ) {
        person.name = "Andrew_R._Morgan";
    }

    if ( person.name === "Anatoly Ivanishin" ){
      person.name = "Anatoli_Ivanishin";
    }

    if ( person.name === "Chris Cassidy" ){
      person.name = "Christopher_Cassidy";
    }

    return getJSON( wikiUrl + person.name );
  });
  return Promise.all(profiles);
}

With those exact URL mappings for Wikipedia, I got 6 'standard' article reponses back from Wikipedia including the image.

Robert O'Toole
Robert O'Toole
6,345 Points

of course the one example they use doesn't work...

i'm a little disappointed in treehouse lately. i have been doing the web development courses and up until the Asynch requests stuff i was totally fine... you guys really arent kidding when you say "beginner" level to "intermediate"... which is fine but a little bit of knowledge on how to actually think like a programmer would help. we went from learning how to write 4-5 lines of JS code to suddenly writing 5 times that amount with complex concepts that were never really taught

Sean Paulson
Sean Paulson
5,365 Points

@Robert O'Toole True they do not go over everything in detail but that is why they provide reading links. These videos will not give you the whole picture. No tutorial will. You must read the documentation.

Matthew Jones
Matthew Jones
9,041 Points

Thank you Bobby! I was going crazy over here

Stanlon Milow
Stanlon Milow
22,373 Points

@KRIS NIKOLAISEN Thank you for your help very much. I was lost but now I get it. Like you said it's because "Aleksandr_Skvortsov_(cosmonaut) and Andrew_R._Morgan respectively will load the correct pages."

Wasn't until I found them on wikipedia that I saw the URLs did it finally make sense.

Brendan Moran
Brendan Moran
13,743 Points

I don't like the approach of testing for and correcting misspellings. The astronauts will obviously change, so this is really hard to maintain. The least hacky way to do this is to use Promise.allSettled() instead of Promise.all(). Check it out on MDN. It makes some creative error handling possible. We could simply pass over the names that don't match, or we could have an optional parameter on the getJSON function where we pass the astronaut name to the function when we are making the API call to wikipedia. That way the name is available for us to pass to the reject() method in getJSON. If we do that, we could build some alternative html in the generateHTML function that at least shows the user the (misspelled) name of the astronaut, and maybe a link to a wikipedia search with the misspelled name, which would lead them to the correct name and article.

Here's how my code differs from the project code, and it works. Currently I just have it skipping anyone whose name was spelled wrong:

function getWikiProfiles(data) {
  const profiles = data.people.map(person => {
    return getJSON(wikiUrl + person.name);
  });
  return Promise.allSettled(profiles);
}

function generateHTML(data) {
  //console.log(data);
  data.forEach(person => {
    if (person.status === 'fulfilled') {
      person = person.value;
      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>
      `;
    }
  });