Is there any possible way via something like a side effect in Redux Saga to cancel an eventChannel?
Given an eventChannel
connecting to an external event/data stream, in this case a Firebase realtime database "child_added"
event:
// action
const types = { SYNC: 'SYNC_TODOS' };
function syncTodos(todos) {
return { types: types.SYNC, todos }
}
// saga
function todosChannel() {
// firebase database ref
const ref = firebase.database().ref('todos/');
const channel = eventChannel(emit => {
const callback = ref.on('child_added', (data) => {
emit({ snapshot: data, value: data.val() })
});
// unsubscribe function
return () => ref.off('child_added', callback);
});
return channel;
}
function* sync() {
const channel = yield call(todosChannel);
try {
while (true) {
const { value } = yield take(todosChannel);
yield put(actions.syncTodos(value));
}
}
finally {
if(yield cancelled()) {
channel.close();
}
}
}
export default function* rootSaga() {
yield fork(sync);
}
Is there any way to use a side effective such as fork() with something like takeEvery() to listen for an action to cancel the event channel and stop listening to the Firebase "child_added"
event/data stream? Or does this require somehow saving a reference to the channel and executing a cancel() on the channel reference itself?
Thank you for any help you can provide.
yield take('SOME_ACITON')
before theyield call(todosChannel)
? – Almucantar