I'm having issues with waiting "one action flow" to finish from start until the end. The app works as usual in client, but while doing stuff server-side it doesn't finish until the end.
To clarify, I'm using both "next-redux-wrapper" and "next-redux-saga" properly, as I can achieve the delayed rendering when I use simpler flow with sagas.
I think the mistake is mostly how I understand (or not) saga effects altogether.
Some of the code is omitted for brevity.
api.saga.js
const makeRequest = ({ body, url, method }) =>
axios({ method, url: url, data: body });
export function* requestWatcher(action) {
const { feature } = action.meta;
try {
const { data: response } = yield call(makeRequest, action.meta);
yield put(apiSuccess({ response, feature }));
} catch (error) {
yield put(apiError({ error: error, feature }));
}
}
export default function* apiSaga() {
yield takeEvery(action => action.type.includes(API_REQUEST), requestWatcher);
}
smallBusiness.saga.js
function* watchApiSuccess(action) {
yield put(
setPositions({ positions: action.payload.positions })
);
yield put(setLoader({ isLoading: false, feature: SMALL_BUSINESS }));
}
function* watchApiError() {
yield put(setLoader({ isLoading: false, feature: SMALL_BUSINESS }));
}
function* watchFetchPositions() {
yield put(
apiRequest({
body: null,
method: 'GET',
url: SMALL_BUSINESS_URL,
feature: SMALL_BUSINESS
})
);
yield put(setLoader({ isLoading: true, feature: SMALL_BUSINESS }));
}
export default function* smallBusinessSaga() {
yield all([
takeLatest(`${SMALL_BUSINESS} ${API_SUCCESS}`, watchApiSuccess),
takeLatest(`${SMALL_BUSINESS} ${API_ERROR}`, watchApiError),
takeLatest(FETCH_POSITIONS, watchFetchPositions)
]);
}
rootSaga.js
export default function* rootSaga() {
yield all([call(smallBusinessSaga), call(apiSaga)]);
}
configureStore.js
store.sagaTask = sagaMiddleware.run(rootSaga);
Client-side function "watchApiSuccess" is called, but server-side it's not. Every generator function is called server-side except for the one already mentioned.
When I simplify the flow with something like the code example below, app will pre-render server-side.
function* watchPrefetchPositions() {
const meta = {
body: null,
method: 'GET',
url: SMALL_BUSINESS_URL,
feature: SMALL_BUSINESS
};
const { data: response } = yield call(makeRequest, meta);
yield put(setPositions({ positions: response.positions }));
}
export default function* smallBusinessSaga() {
yield all([
...
takeLatest(PRE_FETCH_POSITIONS, watchPrefetchPositions)
]);
}
The main issue I have with being unable to have complex flows is that sagas won't be able to do things like normalize and more.