Reputation: 31
I have a saga makes multiple call in it:
function* membersInfoSaga({ payload }) {
const endpoints = [
api.fetchNotifications,
api.fetchPosts,
api.fetchMessages,
api.fetchActivities
]
const responses = yield all(endpoints.map(endpoint => {
try {
return call(endpoint, payload.memberId, payload.page, payload.pageSize)
} catch (error) {
return { data: {} }
}
}))
When a call gets 400 as a response, i want it to continue for the others and return { data: {} }
for the failed call.
I am making calls with Fetch API. And here is my api.js:
function callApi(endpoint, options, unauthorized, isRefreshToken) {
const URL = BASE_URL + endpoint
const ACCESS_TOKEN = localStorage.getItem("access_token")
if (!options) options = {}
options["headers"] = {
"Content-Type": "application/json",
"Accept": "application/json"
}
if (!unauthorized) {
options.headers["Authorization"] = `Bearer ${ACCESS_TOKEN}`
}
return fetch(URL, options)
.then((response) => response.json())
.then((response) => {
if (response.code >= 200 && response.code <= 299) {
return Promise.resolve(response)
} else if (response.code === 401) {
if (isRefreshToken) {
store.dispatch({ type: actionTypes.AUTH_REFRESH_FAILED })
} else {
store.dispatch({
type: actionTypes.INVALID_TOKEN,
payload: { error: response.error.message }
})
return { error: response.error.message }
}
} else {
return Promise.reject(response.error.message)
}
})
.catch((error) => {
return Promise.reject(error)
})
}
And this is the function that i invoke inside saga call method:
const fetchNotifications = (memberId, page, pageSize) => callApi(`notifications/${memberId}?page=${page}&page_size=${pageSize}`)
Upvotes: 3
Views: 1484
Reputation: 31
I have fixed this a little bit different. I've made some updates on my saga and now i can make multiple calls even if some of them returns 400 as response. Here is my solution:
function* fetchMembersInfo(payload) {
yield fork(membersNotificationsSaga, { payload })
yield fork(membersPostsSaga, { payload })
yield fork(membersMessagesSaga, { payload })
yield fork(membersActivitesSaga, { payload })
}
const getNotifications = state => state.members.selectedAccount.notifications.data.notifications
const getPosts = state => state.members.selectedAccount.posts.data.posts
const getMessages = state => state.members.selectedAccount.messages.data.messages
const getActvities = state => state.members.selectedAccount.activites.data.activities
function* membersInfoSaga({ payload }) {
try {
yield call(fetchMembersInfo, payload)
const notifications = yield select(getNotifications)
const posts = yield select(getPosts)
const messages = yield select(getMessages)
const activites = yield select(getActivities)
...
} catch (error) {
...
}
}
Upvotes: 0
Reputation: 4975
The problem in your code is that the try..catch
is where you call the call
effect creator, but not where you yield the resulting effect object. Of course you can't yield directly inside an arrow function either. The way to get around this is to wrap the try..catch
in additional saga generator that will then get executed by the all
effect.
const responses = yield all(
endpoints.map((endpoint) => {
return call(function* () {
try {
return yield call(endpoint, payload.memberId, payload.page, payload.pageSize);
} catch (error) {
return { data: {} };
}
});
})
);
Upvotes: 1