Home > other >  when I use the return keyword in my code, I get only the first value of a list return instead of all
when I use the return keyword in my code, I get only the first value of a list return instead of all

Time:02-12

I wrote a function which when I use the return keyword, I only get the first item of the list returned instead of all items. The code works properly without the return keyword.

code snippet

function generateNames(){
  for (let i = 0; i < 5; i  ) {
    const playersName = fetch('https://www.balldontlie.io/api/v1/players?per_page=5')
      .then(response => response.json())
      .then(json => console.log(json['data'][i]['first_name']))
    // return playersName
  }
} 
generateNames()

The result i get is;

Ike
Ron
Jabari
MarShon
Lorenzo

but when I uncomment the, return playersName line of code, I only get the first value returned.

The result i get is;

Ike

After refactoring the code:

async function generateNames() {
  var playerList = [];
  const playersName = await fetch('https://www.balldontlie.io/api/v1/players?per_page=5')
    .then(response => response.json())
    .then(json => {
      for (let i = 0; i < 5; i  )
        playerList.push(json['data'][i]['first_name'])
    })
  // return playersName
  return playerList;
}
(async () => console.log(await generateNames()))()

CodePudding user response:

I think this is what you want:

async function fetchPlayerNames( count = 1 ) {
    let playersResponse = await fetch(`https://www.balldontlie.io/api/v1/players?per_page=${count}`)
    let players = await playersResponse.json()
    let desiredPlayers = players.data.slice(0, count)
    return desiredPlayers.map( player => player.first_name )
}

(async function main() {
    let names = await fetchPlayerNames(5)
    console.log(names)
})()

Some notes:

  1. async/await is easier to work with than chaining .then handlers, so if your function can be marked async (and some cannot), you should have a strong preference to avoid any .then or .catch inside that function. Your refactor makes the function async, but continues to use .then.

  2. Your refactor won't work anyway, because return playerList will execute before either of the .then functions executes. As a result, I'd expect your refactor to return an empty array immediately every time.

  3. Even though your refactor immediately returns an empty dataset, it still makes the API call five times. That is silly. The URL suggests that the API response can include multiple players, and so your plan should be: (1) make a single request that contains all the rows you want, and then (2) extract the items from that list that you want. If you are careless about making extra network calls, the people who own the API may ultimately block your application because it wastes resources.

  4. Avoid hard-coding things like the 5. That is what is known as a "magic number". Instead, your function should be provided with the desired number. Calling code will get the correct number from a settings file or user input or something else. My version takes it as an argument, but hard-codes it at the call site because there's not really a better place in such a small code sample.

  5. I am going to criticize your naming. Naming matters. Your function does not "generate" names -- it does not create or invent names randomly, but that is what the English word "generate" implies. Your function downloads names from the internet (the correct verb for which is "fetch"). If you name your functions badly, your app will become a mess.

  • Related