Axios API call returning Promise object instead of result?

我的未来我决定 提交于 2019-12-23 17:26:26

问题


Before I start, let me say that I'm new to Javascript and very new to axios API calls, so I'm probably making a rookie mistake...

I have this function getObjects() that's meant to map over an array and return the data from an Axios API call. The API call and map function are both working, but I'm getting a Promise object instead of the data I'm trying to get.

I figure this is because the data is returned before there's enough time to actually get it, but not sure how to fix? I tried a .setTimeout(), but that didn't seem to work.

  getObjects() {
    let newsItems = this.state.arrayofids.map((index) => {
      let resultOfIndex = axios.get(`https:\/\/hacker-news.firebaseio.com/v0/item/${index}.json`).then((res) => {
          let data = res.data;
          //console.log(data.by); // this prints the correct byline, but
                              // all the bylines are printed after
                              // the console.log below...
          if (!data.hasOwnProperty('text')) return data;
        }); /// end of axios request
  return resultOfIndex;
    }); /// end of map
    /// ideally this would end in an array of response objects but instead i'm getting an array of promises...
    console.log(newsItems);
  }

(The extra escape characters are for my text editor's benefit.)

Here's a link to a codepen with the issue - open up the console to see the problem. It's a React project but I don't think any of the React stuff is the issue. EDIT: Codepen is link to working solution using axios.all as suggested below

Thanks!

EDIT: Here is my working solution.

getObjects() {
  let axiosArr = [];
  axios.all(this.state.arrayofids.map((id) => {
      return axios.get(`https:\/\/hacker-news.firebaseio.com/v0/item/${id}.json`)
    })).then((res) => {
      for (let i = 0; i < this.state.arrayofids.length; i++) {
        axiosArr.push(<li key={i} data-url={res[i].data.url} onClick={(e) => this.displayTheNews(e)}>{res[i].data.title}</li>);
      }
      if (axiosArr.length == this.state.arrayofids.length) {
        this.setState({arrayofdata: axiosArr});
        console.log('state is set!');
      }
    })
 }

回答1:


axios.all function should be more appropriate to your current scenario.




回答2:


Your console.log is executing immediately, rather than waiting for the requests to finish, because they are not synchronous. You have to wait for all the responses before you console.log.

OPTION 1 (the hard way): replace your console.log with

newsItems.forEach((promise, index) => {
  promise.then((object)=>{
    newsItems[index] = object
    if (index+1 == newsItems.length) {
      console.log(newsItems)
    }
  })
})


OPTION 2 (the better way): using axios.all

  getObjects() {
    axios.all(this.state.arrayofids.map((id) => {
      return axios.get(`https:\/\/hacker-news.firebaseio.com/v0/item/${id}.json`)
    })).then((res) => {
      console.log(res)
    })
  }

by the way, I would definitely reccommend changing

this.state.arrayofids.map((index) => {
      let resultOfIndex = axios.get(`https:\/\/hacker-news.firebaseio.com/v0/item/${index}.json`)...

to be called id instead of index



来源:https://stackoverflow.com/questions/41523850/axios-api-call-returning-promise-object-instead-of-result

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!