0

Assume we have a Redux-based chat application. What strategy would you use to handle, for instance, undelivered messages? I see two ways:

1. Let the user to initiate message re-sending. It should simplify error handling logic, but may negatively affect usability. It's also possible that user may not even notice that there are any undelivered messages while talking on multiple channels/with multiple persons at the same time.

2. Implement a "worker" that will check for failed messages and will trigger re-sending automatically once in while. In this case user will require less manual work, but the application should have a more sophisticated logic and I don't really understand how to bring it together with Redux.

Also there could be failed requests for other kinds of data. How would you handle such errors? Is it a bad idea to have a pool of serialized failed requests in the Redux state to be re-sent later?

Dmitry Druganov
  • 2,088
  • 3
  • 23
  • 32

2 Answers2

2

I would argue that both these use cases could be elegantly solved by Redux Saga middleware. It has some initial learning curve (especially if you never worked with generators) but it lets you describe long-running processes (“sagas”) that can “take” actions you dispatch, do some async work based on them, use control flow such as conditions and loops, and “put” the result actions when they are ready. See also this answer for an intro to sagas.

Alternatively you can look into Redux Loop which extends reducers with a capability to return “effects” in addition to state changes. This lets you “return an AJAX call” from your reducer, and keep doing that in response to actions, which can also help you implement retries, albeit in a more explicit way.

Community
  • 1
  • 1
Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
1

This isn't really in the scope of Redux, it's more along what redux-thunk seeks to provide in terms of async functionality.

Considering your use-case, you could implement optimistic rendering (i.e. treat all messages as successful until proven otherwise), and have your thunk dispatch a roll-back in case of failure.

A rough idea of what I mean

// your actionCreator / thunk
function (msg) {
    return function(disptach, getState) {
        // optimistic disptach
        dispatch({
            type: "SEND_MESSAGE",
            data: msg
        });

        ajax({
            url: "https://someservice.com/sendMessage",
            method: "POST",
            data: msg,
            onFailure: function(r) {
                // handle failure with rollback
                dispatch({
                    type: "SEND_MESSAGE_FAILED",
                    data: msg,
                    meta: {
                        error: r.responseText
                    }
                });
            }
        });
    }
}

With such an implementation, then your 1st option is more appropriate. Notifying the user of the failure should be handled by a UI component, which reacts to the state-change related to the messaging error.

Sebastien Daniel
  • 4,649
  • 3
  • 19
  • 34