Home > database >  I wanted to get users from an array of names but it throws an error
I wanted to get users from an array of names but it throws an error

Time:12-25

Create an async function getUsers(names), that gets an array of GitHub logins, fetches the users from GitHub and returns an array of GitHub users.

The GitHub url with user information for the given USERNAME is: https://api.github.com/users/USERNAME.

There’s a test example in the sandbox.

Important details:

1.There should be one fetch request per user. 2.Requests shouldn’t wait for each other. So that the data arrives as soon as possible. 3.If any request fails, or if there’s no such user, the function should return null in the resulting array.

Input:array; output:array;

TypeError: r.json is not a function

async function getUsers(names) {
    let requests = names.map(name => fetch(`https://api.github.com/users/${name}`));//gets users
    let users = [];//Final answer
    await Promise.allSettled(requests)
      .then(responses => new Promise(function(resolve) {// returrn correct users promise
        let corrects = [];

        responses.forEach((result) => {
          if (result.value.ok) { //check statuse 200-299
            corrects.push(result);
          } else {
            users.push(result); // else add to Finell answer null 
          }
        })
        resolve(corrects); //return users with 200-299 statuse
      }))
      .then(corrects => Promise.all(corrects.map(r => r.json()))) //processing
      .then(results => results.forEach(result => users.push(result))); //add to finel answer correct requests
    return users;
  }

//Input:array; //output:array;

//TypeError: r.json is not a function

CodePudding user response:

There's a number of things slightly wrong with your code, but I think the main issue is that you're pushing the results of allSettled into 'corrects' but, you want to push the .value instead.

You also don't actually do anything with corrects and only return failed requests.

But here's a version that cleans it all up. I'm assuming you want to ignore failed requests, but not sure, because it's hard to tell from your code:

async function getUsers(names) {

  const requests = names.map(name => fetch(`https://api.github.com/users/${name}`));//gets users
  const results = await Promise.allSettled(requests);

  const successResponses = results
    .filter(result => {
      // Filter out rejected promises and error responses.
      // I think this is what you want but not sure?
      if (result.status!=='fulfilled' || !result.value.ok) return false;
    });

  return Promise.all(successResponses.map(response => response.json()));

}

CodePudding user response:

Promise.allSettled is a very special-purpose function and you will not need it in most cases. There are other pain points like the explicit promise constructor anti-pattern. Instead decompose the problem into smaller, simple parts -

  1. getUser(name) takes a single name and returns a user object or null
  2. getUsers(names) takes a list of names and maps getUser over each

async function getUser(name) {
  try {
    const res = await fetch(`https://api.github.com/users/${name}`)
    return res.ok ? res.json() : null
  }
  catch (err) {
    return null
  }
}

function getUsers(names) {
  return Promise.all(names.map(getUser))
}

getUsers(["ivg", "glennsl", "jeffsco", "nosuchuser111"]).then(console.log, console.error)
.as-console-wrapper { min-height: 100%; top: 0; }

[
  {
    "login": "ivg",
    "id": 2336698,
    "node_id": "MDQ6VXNlcjIzMzY2OTg=",
    ...
  },
  {
    "login": "glennsl",
    "id": 5207036,
    "node_id": "MDQ6VXNlcjUyMDcwMzY=",
    ...
  },
  {
    "login": "jeffsco",
    "id": 4043178,
    "node_id": "MDQ6VXNlcjQwNDMxNzg=",
    ...
  },
  null      // user not found
]
  • Related