I am using redux-saga to upload files and I am trying to figure a way to dispatch an event whenever the upload progress changes:
const data = new FormData();
data.append('file', fileWrapper.file);
const uploadedFile = yield call(request, requestURL, {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
body: data
});
Any idea how to attach an upload progress event?
First of all, the answer depends on how do you do uploadRequest.
It seems like you are using window.fetch API. This API doesn't provide you a way to receive upload progress events.
So, you need to switch to use XMLHttpRequest or a library that wraps it in a convenient way for you. I'd recommend you to look at axios and superagent. They both provide a way to listen to progress events.
The next topic is to how to dispatch progress actions in redux-saga. You need to use fork to create a forked async tasks and dispatch actions there.
function uploadEmitter(action) {
return eventChannel(emit => {
superagent
.post('/api/file')
.send(action.data)
.on('progress', function(e) {
emit(e);
});
});
}
function* progressListener(chan) {
while (true) {
const data = yield take(chan)
yield put({ type: 'PROGRESS', payload: data })
}
}
function* uploadSaga(action) {
const emitter = uploadEmitter()
yield fork(progressListener, emitter)
const result = yield call(identity(promise))
yield put({ type: 'SUCCESS', payload: result })
}
Source: https://github.com/redux-saga/redux-saga/issues/613#issuecomment-258384017
P.S. in my personal opinion, redux-saga is not an appropriate tool to implement such kind of functionality. Would be much cleaner to do this with redux-thunk:
function uploadAction(file) {
return dispatch => {
superagent
.post('/api/file')
.send(action.data)
.on('progress', function(event) {
dispatch({type: 'UPLOAD_PROGRESS', event});
})
.end(function(res) {
if(res.ok) {
dispatch({type: 'UPLOAD_SUCCESS', res});
} else {
dispatch({type: 'UPLOAD_FAILURE', res});
}
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With