Reputation: 245
I am new to React and Promises.
My purpose is - Collect array of objects from several Search Services and then transfer whole array to the State.
PNP.SearchResults
is a Promise
In code below this.setState
is performing earlier then array is ready.
How to fix it?
private getSearchResults() {
const allSearchResults = []
this.state.resultSources.forEach(rSource =>{
this.props.searchService.search(this.props.AdditionalQuery, this.state.activePage, this.props.PageSize, rSource.sourceGuid).then((results: PNP.SearchResults) => {
allSearchResults.push({Results: results, sourceGuid: rSource.sourceGuid});
console.log("push");
}).catch(() => {});
})
this.setState({PrimaryResults2: allSearchResults} as any);
console.log("state updated");
}
Now console.log("state updated")
fires earlier then console.log("push")
.
But I need vice versa
Upvotes: 0
Views: 630
Reputation: 21
If i understand correctly, you need to first push the search results into allSearchResults array and then setState. Why not use async await and a basic for loop instead of .then. When you use .then, only the code in the .then callback will execute after the promise is resolved but the other code outside it like this.setState, console.log won't wait till you push all the search results.
async func() {
const allSearchResults = [];
for(let i=0; i<this.state.resultSources.length; i+=1){
const item = await this.props.searchService.search(this.props.AdditionalQuery, this.state.activePage, this.props.PageSize, this.state.resultSources[i].sourceGuid)
allSearchResults.push({Results: item, sourceGuid: this.state.resultSources[i].sourceGuid})
}
this.setState({PrimaryResults2: allSearchResults} as any, () => {console.log("state updated")})
}
Upvotes: 1
Reputation: 1961
Because of this.props.searchService.search
is async function.
You should await result to make sure data return.
private async getSearchResults() {
const allSearchResults = []
for (const rSource of this.state.resultSources) {
await this.props.searchService.search(this.props.AdditionalQuery, this.state.activePage, this.props.PageSize, rSource.sourceGuid).then((results: PNP.SearchResults) => {
allSearchResults.push({Results: results, sourceGuid: rSource.sourceGuid});
console.log("push");
}).catch(() => {});
}
this.setState({PrimaryResults2: allSearchResults} as any);
console.log("state updated");
}
Upvotes: 1