3

So basically i created a loop that takes values from an array and puts those values in a a loop using the youtube api . The youtube link works fine if I access it from within the loop, but outside the loop '(when i run the console.log({urllist})', i get an empty array.What I want to do is push all the values into the urllist empty array then transfer for them to the state variable('videos')

The function I am referring to is the videoUrls

class MusicCharter extends React.Component{
 constructor(){
    super();
    this.state= {
      data:[],
      videos:[],
  }
 }

 componentDidMount(){
  XHR.onreadystatechange = function(){
    if(XHR.readyState === 4 && XHR.status === 200) {
        var url = XHR.responseText;
        this.setState({data:(JSON.parse(url).tracks.track)})
    }
  }.bind(this)
  
  XHR.open("GET","http://ws.audioscrobbler.com/2.0/?method=chart.gettoptracks&api_key=xxxxxxx&format=json");
  XHR.send();
}

videoUrls=()=>{
  let i=0;
  let urllist=[]
  for(i;i< this.state.data.length;i++){
      fetch(`https://www.googleapis.com/youtube/v3/search?part=snippet&q=${this.state.data[i].name}&key=xxxxxxxxxxx0`)
      .then(response=> {
        return response.json()
    })
     .then(data=>{
        return(urllist.push(data.items[0]))})
   }
   console.log({urllist})
 }
Udendu Abasili
  • 1,163
  • 2
  • 13
  • 29

2 Answers2

8

Your for loop does not iterate asynchronously but you can get around this by putting your for loop inside an async function Asynchronous Process inside a javascript for loop and awaiting the result of the asynchronous operations

videoUrls = async () => {
  let i=0;
  let urllist=[]
  for(i;i< this.state.data.length;i++){
      const response = await fetch(`https://www.googleapis.com/youtube/v3/search?part=snippet&q=${this.state.data[i].name}&key=xxxxxxxxxxx0`)
      const json = await response.json()
      urllist.push(json.items[0])
      console.log({urllist})
    }
 }

This prevents the for loop from incrementing until both the fetch and conversion of the response to json is complete

Maxwelll
  • 2,174
  • 1
  • 17
  • 22
6

You can use Promise.all

videoUrls = () =>{
  const promises = this.state.data.map(item => {
    return fetch(`https://www.googleapis.com/youtube/v3/search?part=snippet&q=${this.state.data[i].name}&key=xxxxxxxxxxx0`)
      .then(response=> {
      return response.json()
    });
  });

  Promise.all(promises).then(results => {
    const videos = results.map(result => result.items[0]);
    console.log(videos);
    this.setState({videos});
  })
}
Zohaib Ijaz
  • 21,926
  • 7
  • 38
  • 60