function* imageUploadfunctionCall(payload) {
for (let image of payload.payload) {
const {response, error} = yield call(imageUploadRequest(image))
if (response) {
yield put({type: ON_UPLOAD_SUCCESS, payload: image})
} else if (error) {
console.log('error', error)
}
}
}
export function* watchImageUpload() {
while (true) {
let workerTask = yield takeEvery(
ON_UPLOAD_PROGRESS,
imageUploadfunctionCall
)
yield take(ON_CANCEL_BATCH_UPLOAD)
yield cancel(workerTask)
}
}
There is multiple ways you can do this, for example you can use an in-between saga with a race
effect:
function* imageUploadfunctionCall(payload) {
for (let image of payload.payload) {
const {response, error} = yield call(imageUploadRequest(image))
if (response) {
yield put({type: ON_UPLOAD_SUCCESS, payload: image})
} else if (error) {
console.log('error', error)
}
}
}
function* imageUploadSaga(payload) {
yield race([
call(imageUploadfunctionCall, payload),
take(a => a.type === ON_CANCEL_BATCH_UPLOAD && a.id === payload.id),
])
}
export function* watchImageUpload() {
yield takeEvery(ON_UPLOAD_PROGRESS, imageUploadSaga)
}
The code above assumes that you send an id
property for both the ON_UPLOAD_PROGRESS
& ON_CANCEL_BATCH_UPLOAD
actions so you can identify which one to cancel.
On a side note, in the upload saga you have:
yield call(imageUploadRequest(image))
which should be probably instead
yield call(imageUploadRequest, image)
(unless imageUploadRequest
is a function factory).
For more complex cases you could hold a map of tasks & ids.
export function* watchImageUpload() {
const taskMap = {}
yield takeEvery(ON_CANCEL_BATCH_UPLOAD, function* (action) {
if (!taskMap[action.payload]) return
yield cancel(taskMap[action.payload])
delete taskMap[action.payload]
})
while (true) {
let payload = yield take(ON_UPLOAD_PROGRESS, imageUploadSaga)
const workerTask = yield fork(imageUploadfunctionCall, payload)
taskMap[payload.id] = workerTask
}
}
Again, you need some id in both actions.