I'm using the tus Protocol to upload files and this protocol has some callback functions. What I'm trying to do is to yield an action and do something else, but I see that I can't use yield inside the callback.
Bellow is a piece of code from the saga function that contains the callback.
const upload = new tus.Upload(payload,
{
endpoint: `${baseURL}files/`,
chunkSize: fileChunkSize,
headers: { 'Authorization': `Bearer ${jwtToken}`, 'SelectedDatabase': selectedDatabase },
onSuccess: () => {
console.log("Upload Finished");
toast.done(toastId);
toastSuccess(`File (${payload.name}) was successfully uploaded.`);
//yield put(sendFilesSuccess()); TODO: how to call this?
}
});
upload.start();
I read something related to channels, but I couldn't understand it very well, so any help would be appreciated.
This is a great use case for Channels because they make handling event callbacks as if it were just like handling Redux actions. To wait and read from a channel, it's as simple as doing a take
.
function uploadChannelCreator(payload, /* ... */) {
return eventChannel(emitter => {
const upload = new tus.Upload(payload,
{
endpoint: `${baseURL}files/`,
chunkSize: fileChunkSize,
headers: { 'Authorization': `Bearer ${jwtToken}`, 'SelectedDatabase': selectedDatabase },
onSuccess: () => {
emitter('SUCCESS');
}
// ... Emit other messages based on different events (i.e. onFailure)
});
upload.start();
return () => {}
}
)
}
function* uploadSaga(payload, /* ... */) {
const chan = yield call(uploadChannelCreator, payload, /* ... */); // 1. Call Channel
const msg = yield take(chan); // 2. Wait for channel to emit a message
// Rest of code... (Add error handling if necessary).
console.log("Upload Finished");
toast.done(toastId);
toastSuccess(`File (${payload.name}) was successfully uploaded.`);
}