jeffbski / redux-logic

Redux middleware for organizing all your business logic. Intercept actions and perform async processing.
MIT License
1.81k stars 107 forks source link

cancelling by id #56

Open zdila opened 7 years ago

zdila commented 7 years ago

Our usecase is that we add toasts with payload { "type": "TOASTS_ADD", "payload" { "id": <toast_unique_id>, "timeout": <optional_timeout>, "message": <message> } } and remove them with payload { "type": "TOASTS_REMOVE", "payload": <toast_unique_id>}. Removal is done manually or on timeout.

If it is done manually then we would like to cancel logic (waiting on toast timeout) by <toast_unique_id>. From API it seems that only type can be used for cancellation, without any payload support.

Therefore we've created "workaround":

const clearTimeoutMap = new Map();

const logic1 = createLogic({
  type: 'TOASTS_ADD',
  process({ action: { payload: { timeout, id } } }, dispatch, done) {
    if (typeof timeout === 'number') {
      const to = setTimeout(() => {
        clearTimeoutMap.delete(id);
        dispatch(toastsRemove(id));
        done();
      }, timeout);

      clearTimeoutMap.set(id, () => {
        clearTimeoutMap.delete(id);
        clearTimeout(to);
        done();
      });
    } else {
      done();
    }
  },
});

const logic2 = createLogic({
  type: 'TOASTS_REMOVE',
  process({ action: { payload: id } }) {
    const ct = clearTimeoutMap.get(id);
    if (ct) {
      ct();
    }
  },
});

Is this approach OK?

zdila commented 7 years ago

Just in case, here is the full implementation with additional features:

And one of the usages: https://github.com/FreemapSlovakia/freemap-v3-react/blob/master/src/components/DistanceMeasurementResult.js#L153

jeffbski commented 7 years ago

Thanks @zdila I had the basics started in my notification example, but you have taken it much further. Thanks for sharing.