Skip to content

Instantly share code, notes, and snippets.

@jmporchet
Created April 17, 2019 08:37
Show Gist options
  • Save jmporchet/3b273b81d90402f3df94c607e04e6de9 to your computer and use it in GitHub Desktop.
Save jmporchet/3b273b81d90402f3df94c607e04e6de9 to your computer and use it in GitHub Desktop.
The correct way to make several network requests in one saga with yield
import { takeEvery, call, put, all, select } from 'redux-saga/effects';
import * as ActionTypes from '../actions';
import { networkService } from '../services/networkService';
export function* getAutocompleteInfo(action) {
const token = yield select(state => state.user.token);
const autocompleteSuggestions = yield call(
networkService.requestAutocompleteInfo,
action.query,
token
);
if (autocompleteSuggestions.errors) {
yield put(
ActionTypes.getAutocompleteInfoError(
autocompleteSuggestions.errors.detail
)
);
} else {
// this is the correct syntax to make several fetch calls, wait for their result, then continue execution
const suggestedItems = yield all(
autocompleteSuggestions.results.map(item => {
// don't forget to actually return the value of the call in the map
// no need to yield here because of the 'yield all' above
return call(networkService.requestInformation, item.id, token);
})
);
const itemsThatHaveInfo = suggestedItems
.filter(item => item.count > 0)
.map(item => item.id);
const filteredSuggestions = autocompleteSuggestions.results.filter(item =>
itemsThatHaveInfo.includes(item.id)
);
yield put(ActionTypes.getAutocompleteInfoResult(filteredSuggestions));
}
}
export default function* rootSaga() {
yield all([
takeEvery(ActionTypes.GET_AUTOCOMPLETE_RESULTS, getAutocompleteInfo)
// other actions
]);
}
import { URL } from '../constants/Settings';
export const networkService = {
async requestAutocompleteInfo(searchTerm, token) {
if (!token) return { error: 'token missing' };
try {
const req = await fetch(
`${URL}/items/autocomplete/?query=${searchTerm}`,
{ method: 'GET', headers: { Authorization: `Bearer ${token}` } }
);
return await req.json();
} catch (e) {
return { error: e.message };
}
},
async requestInformation(itemId, token) {
if (!token) return { error: 'token missing' };
try {
const req = await fetch(
`${URL}/items/${itemId}/nutrition_facts/`,
{ method: 'GET', headers: { Authorization: `Bearer ${token}` } }
);
const res = await req.json();
return { id: itemId, count: res.count };
} catch (e) {
return { error: e.message };
}
}
};
@alejandropaciotti
Copy link

Excellent !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment