Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

131
Views
async function doesn't wait await fetch

I have a function that must validate some artist from Spotify API, but when I run it artists[] remains empty because the function is not waiting the fetch, it fills the variable user without having set artists.

let artists = []

function setArtists(input) {
  artists.length = 0
  let parsedInput = input.value.split(",")
  parsedInput.forEach(artist => {
    validateArtist(artist)
  })
}

async function validateArtist(s) {
  let token = localStorage.getItem("Token")
  let url = "https://api.spotify.com/v1/search?type=artist&q=" + s
  console.log(url)
  await fetch(url, {
      "method": "GET",
      "headers": {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        "Authorization": "Bearer " + token,
      }
    })
    .then(response => {
      if (response.status === 401) {
        refreshToken(s)
      }
      return response.json()
    })
    .then(searchedResults => searchedResults.artists.items.length != 0)
    .then(isArtist => {
      if (isArtist) {
        artists.push(s)
      }
    })
}

Here is where I call the function, I call it before so it can fill artists variable.

setArtists(document.getElementById("artistiPreferiti"))
    var user = {
            username: document.getElementById("username").value,
            email: document.getElementById("email").value,
            password: document.getElementById("password").value,
            gustiMusicali: document.getElementById("gustiMusicali").value,
            artistiPreferiti: artists
    }    
 

How can i fix it?

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

You can use Promise.all() like:

const artists = ['first', 'second'];

const promises = artists.map(artist => fetch(url+artist));

Promise.all(promises)
.then(response => {
  // handle response
})
.catch(err);

or

const returnedData = await Promise.all(promises).catch(err);

about 4 years ago · Juan Pablo Isaza Report

0

Looking at the pieces one at a time, setArtists must indeed by async and should probably run the validation currently (since the validations are not interdependent).

There's no need for the artists global in the containing scope. In fact, having it will encourage errors.

// clarifying... input is a comma-delimited string describing artists
// validate each one with spotify, and return an array of the valid artists
async function setArtists(input) {
  let parsedInput = input.value.split(",")
  let promises = parsedInput.map(validateArtist);
  let results = await Promise.all(promises);  // validate all of them at once
  // return just the valid inputs, not the nulls
  return results.filter(r => r);
}

The validateArtist method mixes async styles. Here it is with uniform style and with a clearer objective: to just validate and return an artist...

// given the params of an artist, lookup on spotify and return a
// a promise that resolves to the input artist if valid, null otherwise
async function validateArtist(s) {
  const token = localStorage.getItem("Token")
  const url = "https://api.spotify.com/v1/search?type=artist&q=" + s
  console.log(url)
  const response = await fetch(url, {
      "method": "GET",
      "headers": {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        "Authorization": "Bearer " + token,
      }
  });
  if (response.status === 401) {
    refreshToken(s)
  }
  const searchedResults = await response.json();
  const isArtist = searchedResults.artists.items.length != 0;
  // notice, no side-effects here, resolve to the input artist or null
  return isArtist ? s : null;
}

Lastly, your caller must be async also, and await the setArtists result...

async function theCaller() {
  // notice - no need for a global. now it's a local here...
  let artists = await setArtists(document.getElementById("artistiPreferiti"))
  var user = {
    username: document.getElementById("username").value,
    email: document.getElementById("email").value,
    password: document.getElementById("password").value,
    gustiMusicali: document.getElementById("gustiMusicali").value,
    artistiPreferiti: artists
  } 
  // ...

As a side note, there might be valuable stuff in the artist array that spotify returns, some super set of the data you queried with. If you'd rather keep the results around, you can make up a policy to pick the first matching artist returned in the array of spotify matches...

// updating the functional comment:
// given the params of an artist, lookup on spotify and return a
// a promise that resolves to the first found artist or null if no matches are found

  .then(searchedResults => {
    let items = searchedResults.artists.items;
    return items.length ? items[0] : null;
  });
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!