We have a multiple custom React file input components(let's say 4 different input file sections). Need to upload file for each component which internally triggers an action and call api call to upload the file to server.
So here the problem here is the api call for all file uploads is same. We need sequence the actions(first file upload action resolve first and second and so on) so all apis will execute sequencially (as per our project requirement we need to pass one API response header xsrf token as a request header to next calling api ).
Here is the code what I've tried.
import { take, actionChannel, call, put, fork, takeEvery, takeLatest } from 'redux-saga/effects';
import { AnyAction } from 'redux';
import { ServicesType } from '../services/types';
import { uploadLossOfAccountMaleSuccess, uploadLossOfAccountFemaleSuccess fetchDataFailure, UploadExistingAccountMaleSuccess, UploadExistingAccountFemaleSuccess} from './actions';
import {UPLOAD_ACCOUNT_LOSS_REQUEST_MALE, UPLOAD_ACCOUNT_LOSS_REQUEST_FEMALE, UPLOAD_ACCOUNT_EXIST_REQUEST_MALE, UPLOAD_ACCOUNT_EXIST_REQUEST_FEMALE} from './actionTypes';
// services are written for making an axios api calls
type Services = Pick<ServicesType, 'FileUpload'>;
function uploadLossOfAccount(services: Services, gender: string) {
return function* (action: AnyAction) {
try {
//postData is function which makes an axios call
const data = yield call(services.FileUpload.postData, action.payload);
gender=="male"?yield put(uploadLossOfAccountMaleSuccess(data)): yield put(uploadLossOfAccountFemaleSuccess(data));
} catch (error) {
// Dispatch failure action
yield put(fetchDataFailure(error.message));
}
}
function UploadExistingAccount(services: Services, gender: string) {
return function* (action: AnyAction) {
try {
//postData is a function that makes an axios call
const data= yield call(services.FileUpload.postData, action.payload);
gender=="male"? yield put(UploadExistingAccountMaleSuccess(data)): yield put(UploadExistingAccountFemaleSuccess(data));
} catch (error) {
// Handle error if needed
}
}
//sequencing actions
**function* watchRequests(services:Services) {
// Create an action channel for actions
const requestChannel = yield actionChannel([UPLOAD_ACCOUNT_LOSS_REQUEST_MALE, UPLOAD_ACCOUNT_LOSS_REQUEST_FEMALE, UPLOAD_ACCOUNT_EXIST_REQUEST_MALE, UPLOAD_ACCOUNT_EXIST_REQUEST_FEMALE]);
while (true) {
// Take the next action from the channel
const action = yield take(requestChannel);
switch (action.type) {
case UPLOAD_ACCOUNT_LOSS_REQUEST_MALE:
yield call(uploadLossOfAccount, services, "male");
break;
case UPLOAD_ACCOUNT_LOSS_REQUEST_FEMALE:
yield call(uploadLossOfAccount, services, "female");
break;
case UPLOAD_ACCOUNT_EXIST_REQUEST_MALE:
yield call(UploadExistingAccount, services, "male");
break;
case UPLOAD_ACCOUNT_EXIST_REQUEST_FEMALE:
yield call(UploadExistingAccount, services, "female");
break;
//other actions
}
}
}**
function* fileUploadSaga(services:Services):any{
return [yield watchRequests(services]
}
export default fileUploadSaga
rootSaga.js
export default function* rootSaga() {
const totalSagas=[...fileUploadSaga, ...remainingSagas]
yield all(totalSagas);
}
I suspect that there is a problem in fileuploadSaga function. API call it self is not being made through above code. Please suggest any changes to make it work properly. I am not able to found out where I am making mistake. Please help in this case to make all the actions execute sequencially.
Try to modify watchRequests generator function like below. and also remove the return statement from the fileUpload saga. It may work.
function* watchRequests(services: Services) {
// Create an action channel for actions
const requestChannel = yield actionChannel([
UPLOAD_ACCOUNT_LOSS_REQUEST_MALE,
UPLOAD_ACCOUNT_LOSS_REQUEST_FEMALE,
UPLOAD_ACCOUNT_EXIST_REQUEST_MALE,
UPLOAD_ACCOUNT_EXIST_REQUEST_FEMALE,
]);
while (true) {
// Take the next action from the channel
const action: AnyAction = yield take(requestChannel);
switch (action.type) {
case UPLOAD_ACCOUNT_LOSS_REQUEST_MALE:
yield call(uploadLossOfAccount(services, 'male'), action);
break;
case UPLOAD_ACCOUNT_LOSS_REQUEST_FEMALE:
yield call(uploadLossOfAccount(services, 'female'), action);
break;
case UPLOAD_ACCOUNT_EXIST_REQUEST_MALE:
yield call(UploadExistingAccount(services, 'male'), action);
break;
case UPLOAD_ACCOUNT_EXIST_REQUEST_FEMALE:
yield call(UploadExistingAccount(services, 'female'), action);
break;
// other actions
}
}
}
function* fileUploadSaga(services: Services): any {
yield fork(watchRequests, services);
}
export default fileUploadSaga;