Reputation: 798
I'm trying to make several requests using all()
and map()
functions and if result comes and have the expected shape, I want to call another action to save the result in my store.
Here's a part of my saga, but it's not working as expected - the getAvailabilityRequest
is not executed.
yield all(
part1.map((p1) => {
return part2.map((p2) => {
return tld.map((t) => {
const response = call(getAvailabilityRequest, `${p1}${p2}.${t}`);
if (response && isAvailabilityResult(response)) {
const index: AvailabilityIndex = { part1: p1, part2: p2, tld: t };
return put(setAvailabilityActionCreator({ index, item: response }));
}
});
});
})
);
Also I've tried this
const response = yield all(
part1.map((p1) => {
return part2.map((p2) => {
return tld.map((t) => {
return {index: { part1: p1, part2: p2, tld: t }, result: call(getAvailabilityRequest, `${p1}${p2}.${t}`)};
});
});
})
);
to keep the data about index
, but still, getAvailabilityRequest
is not being called.
Is there a way I can change the saga to get expected results?
Upvotes: 0
Views: 1806
Reputation: 41893
You are not returning the call so it can't be yielded. What's more important - yield all
expects an array of functions that return Promises. Dispatching an action doesn't return a Promise and this is what you are doing here. put
are a non-blocking calls.
I'd suggest you to delegate the logic to a separate generator function.
function* getAvailability(p1, p2, t) {
try {
const response = call(getAvailabilityRequest, `${p1}${p2}.${t}`);
if (response && isAvailabilityResult(response)) {
const index: AvailabilityIndex = { part1: p1, part2: p2, tld: t };
yield put(setAvailabilityActionCreator({ index, item: response }));
}
} catch (error) {
// error logic
}
}
Edit: It seems like the nested map
is an issue. yield all
expects a flat array.
const calls = yield [];
yield part1.forEach((p1) => {
part2.forEach((p2) => {
tld.forEach((t) => {
calls.push(call(getAvailabilityRequest, `${p1}${p2}.${t}`));
});
});
});
const response = yield all(calls);
Upvotes: 1