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})
 }

2 Answers 2

9

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

Sign up to request clarification or add additional context in comments.

1 Comment

i made a bit of modification but thanks lol. i didnt think of using that
7

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});
  })
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.