amplitude / redux-query

A library for managing network state in Redux
https://amplitude.github.io/redux-query
Other
1.1k stars 67 forks source link

Feature: `Error` and `Rollback` config keys => fns for handling error cases #9

Closed MrNice closed 7 years ago

MrNice commented 7 years ago

With redux query, if a user requests an entity which does not exist, how do I let them know?

My suggestion is to add two new functions alongside update and optimisticUpdate: error to handle cases where no client state was optimistically updated, and rollback to handle undoing optimistic updates.

S = State
S` = newState (State prime)
U = update
OU = optimistic update
E = error
R = Rollback

Successful path where network and back end succeed:

S` = OU(S)
S`` = U(S`)

Failure path where network or back end fails:

S` = OU(S)
S`` = R(S`)
S`` === S // Identity, must be true or else the rollback doesn't roll back
ryanashcraft commented 7 years ago

@MrNice Can you provide an example where these two options would be really useful?

MrNice commented 7 years ago

Totally.

So, a user creates a new blog post and submits it through update. It gets added to the database and the return code is a nice 200. The page show a loading indicator for the entire duration of the request response cycle, which is OK because we never want the user to think a blog post exists in the db when it does not, because they might close the page, etc.

We care less about tags, so when the user then adds a tag to the existing blog post, we optimistically update the ui and give the tag a temp_tag_id_${Date.now()}, and add a reference to that ID to the blog in redux.

If the back end succeeds, we migrate the temp id to a real id in the tags state slice and in the blog's tags array.

If it fails, I need to be able to allow the user to cancel the tag save attempt, which means either a retry, or a rollback. The rollback would unset the temp_id link in the blog tag array and remove the temp tag entity.

An error case would let me capture the error and send it to the UI in some fashion

My goal is to allow redux-query to control the redux state transitions for mutations which succeed or fail, not just successful ones.

At work I've been working on a react-redux calculus and its properties, which I hinted at in opening this issue.

Recap in case I drifted too much: error would let me tell the user why a resource can't load, rollback would let me undo optimistic state changes and then tell the user why they couldn't actually do an action which seemed to succeed.

MrNice commented 7 years ago

@ryanashcraft I've been thinking about this and think it might be sensible to replace update w/ a small middleware pipeline because we're fundamentally dealing w/ http which has the application / protocol separated. Right now, update only takes body, and that can be implemented as a really simple one function middleware pipeline.But I could then implement error / rollback etc as a slightly different pipeline.

ryanashcraft commented 7 years ago

@MrNice I don't understand the HTTP middleware pipeline proposal.

I'm not sold on the utility of rollback. With your example – wouldn't that just work with how "rollback" currently works in redux-query where it just reverts the entities?

I do think there's something missing in the API to get error metadata. But I think this data should belong to the queries state, not entities state. If we do something like what I proposed here, would that take care of that use case?

ryanashcraft commented 7 years ago

Implemented rollback for 2.0. An errorsReducer can be used for tracking response data for failed queries.