-
-
Save space11/0e9b57e6997999a066c309568b2db6c2 to your computer and use it in GitHub Desktop.
Example of using redux-saga eventChannel with axios/fetch etc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {eventChannel, END} from 'redux-saga' | |
function createUploaderChannel(key, files){ | |
return eventChannel(emit => { | |
const onProgress = ({total, loaded}) => { | |
const percentage = Math.round((loaded * 100) / total) | |
emit(percentage) | |
} | |
axios.post('url', files, { | |
requestId: key, | |
uploadProgress: onProgress, | |
}).then(() => { | |
emit(END) | |
}).catch(err => { | |
emit(new Error(err.message)) | |
emit(END) | |
}) | |
const unsubscribe = () => {} | |
return unsubscribe | |
}) | |
} | |
function* uploadProgressWatcher(fileName, channel) { | |
while(true){ | |
try{ | |
const progress = yield take(channel) | |
yield put(actions.uploadFiles.progress(progress)) | |
} | |
catch(err){ | |
yield put(actions.uploadFiles.progress(err)) | |
} | |
finally{ | |
if(yield cancelled()) channel.close() | |
} | |
} | |
} | |
function* uploadFile(fileName, index, files) { | |
try{ | |
const formData = new FormData() | |
formData.append('files', files[fileName]) | |
const uploadChannel = yield call(createUploaderChannel, fileName, formData) | |
yield fork(uploadProgressWatcher, fileName, uploadChannel) | |
} | |
catch(err){ | |
yield* actions.uploadFiles.failure(err) | |
} | |
} | |
function* uploadFiles({payload}) { | |
const {files} = payload | |
yield put(actions.uploadFiles.progress(payload)) | |
yield all( | |
Object.keys(files).map(uploadFile) | |
) | |
} | |
export default function*() { | |
takeLatest(actions.uploadFiles, uploadFiles) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment