Reputation: 220
How do I go about waiting for all the posts to be pushed to the posts array before updating the state?
I had to iterate over an array of post ID's to get the top posts on HackerNews and then turned all those ID's into singular post links and want to store the data from the single post links in an array so I can iterate over that array to render it in the DOM.
import React, {Component} from 'react';
import axios from 'axios';
import Post from './Post';
class ContentWrapper extends Component {
constructor(props){
super(props);
this.state = {
posts: []
}
}
componentDidMount(){
const topStories = 'https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty';
// `https://hacker-news.firebaseio.com/v0/item/.json?print=pretty`
axios(topStories).then(res => {
const posts = [];
res.data.map(val => {
const url = `https://hacker-news.firebaseio.com/v0/item/${val}.json?print=pretty`;
return axios.get(url).then(res => {
posts.push(res.data);
}).then(res => this.setState({posts: res}));
});
});
}
render() {
const posts = this.state.posts.map((val, i) => {
return <Post key={i} title={val.title} author={val.by} />
});
return (
<div className="content-wrapper">
<h2>{this.props.currentSource}</h2>
{posts}
</div>
)
}
}
export default ContentWrapper;
Upvotes: 15
Views: 27659
Reputation: 7407
You will have to use Promise.all
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
const topStories =
"https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty";
axios(topStories).then(res => {
const posts = [];
const requests = res.data.map(val => {
const url = `https://hacker-news.firebaseio.com/v0/item/${val}.json?print=pretty`;
return axios.get(url).then(res => {
posts.push(res.data);
});
});
// Wait for all requests, and then setState
return Promise.all(requests).then(() => {
this.setState({
posts
});
});
});
Test it here: https://runkit.com/embed/8pac53dhmy2y
Update There is also Promise.allSettled
which might be better in some cases if there are any errors in the promise array; https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
Upvotes: 27