I have an issue with something that look like very easy..
To summarize, I have many stores ans many users that are related to stores by a storeId
In my componentDidMount, I call a service "getByStore" which is a Promise that returns a list of members by storeId (members that are based on a model Member).
Until there, all is ok. Now I have to set additionnal value for every members. So I map on all members and I trigger a new Promise which return a list of escorts.
I assign the promise return into the right value of the Member.
After that, I set the values in the component state and this is sent to an other component.
The problem is when I console.log in the final component, the value is always set to null. It's like my array map never happened.
It's hard to explain, so let me know if I forgot something to help the understanding.
Here is the code with the array map :
componentDidMount() {
const { storeId, store } = Auth.user();
MemberService.getByStore(storeId).then((members) => {
const options = {
fromDate: this.state.period.from,
toDate: this.state.period.to,
};
const membersWithEscorts = members.map((member) => {
EscortService.getLastEscorts(member.id, options).then((escorts) => {
member.setEscortHistory(new EscortHistory(escorts));
});
return member;
});
this.setState({ members: membersWithEscorts, store });
});
}
and here is the code which receive the members :
render() {
const { members } = this.props;
return (
<div id="member-list" className="grid">
<div className="grid-sizer" />
{members.map(member => (
<div key={member.id} className="grid-item">
<MemberCard linkTo={`/member/${member.id}`} member={member} />
</div>
))}
</div>
);
}
Thanks !
You should wait for all escort histories to be set before passing that to setState:
const membersWithEscorts = Promise.all(members.map((member) => {
return EscortService.getLastEscorts(member.id, options).then((escorts) => {
member.setEscortHistory(new EscortHistory(escorts));
return member;
});
}));
membersWithEscorts.then(members => {
this.setState({ members, store });
});
That might be more elegant with async
/ await
:
async componentDidMount() {
const { storeId, store } = Auth.user();
const members = await MemberService.getByStore(storeId);
const membersWithEscorts = await Promise.all(members.map(m => this.addHistory(m)));
this.setState({ members: membersWithEscorts, store });
}
async addHistory(member) {
const options = {
fromDate: this.state.period.from,
toDate: this.state.period.to,
};
const escorts = await EscortService.getLastEscorts(member.id, options);
member.setEscortHistory(new EscortHistory(escorts));
return member;
}