I am a newb so lack of info there may be here. The following saga is registered
function* onboardingListener() {
yield takeEvery(ENROLL_CRED_STATUS_REQUEST, onboarding);
}
function* onboarding(enrollFormUsername) {
// a few lines of code that are not important 'I think'
yield put(enrollGetContactByUsername(username));
const { contactSuccess } = yield race({
contactSuccess: take(ENROLL_CONTACT_FIND_SUCCESS),
contactFailure: take(ENROLL_CONTACT_FIND_FAILURE),
});
}
export function enrollGetContactByUsername(username) {
const config = {
baseURL: ENV_VARS.BASE_URL_CONTACT,
url: '/contact/enroll',
method: 'GET',
params: {
email: `${username}`,
},
};
return {
type: 'API_CALL',
config,
auth: false,
spinner: true,
successAction: ENROLL_CONTACT_FIND_SUCCESS,
failureAction: ENROLL_CONTACT_FIND_FAILURE,
};
}
I see ENROLL_CRED_STATUS_REQUEST wired up which I guess is the start of when onboarding will call so not sure I need to supply all that react-redux code.
Looking in redux documentation, I see code like this
const token = yield call(Api.authorize, user, password)
yield put({type: 'LOGIN_SUCCESS', token})
which makes sense to me. I do not get how my above code is calling the remote server and why call() nor fork() is being called in the above code. How exactly is the above code working? (I feel like I am really close to connecting the dots but am not quite there)
enrollGetContactByUsername
is an action creator that creates a new action of type API_CALL
which you then dispatch in onboarding
saga. I suspect you have another saga somewhere running and listening on this action to handle the request. Said saga is then probably looking similar to the next snippet, except instead of Api.authorize
it uses the provided config instead. So something like:
function * apiCallSaga() {
yield takeEvery(API_CALL, function * (action) {
try {
const method = axios[config.method.toLowerCase()]
const fullUrl = config.baseURL + config.url
const {data} = yield call(method, fullUrl, config.params)
yield put({type: config.successAction, data})
} catch (err) {
yield put({type: config.failureAction, err})
}
}
}
To answer your second question. When you want to call a function that returns a promise, you can use either call
or fork
. The difference is that yielding call
waits for the result - similar to await
in async function - and so you can assign it to variable to get the result of the promise. On the other hand fork
is non-blocking effect that instead returns immediately a "task descriptor" which is something like a promise in the saga world. You can then e.g. use the join
effect to wait for the result later in the code. In 99% cases, when making api request, you want to get the result at the line of code where you are making the request and so you will use the call
effect.