omcljs / om

ClojureScript interface to Facebook's React
6.65k stars 364 forks source link

Specify :remote reads in transact! #897

Open decoursin opened 6 years ago

decoursin commented 6 years ago

Transition the application state. transact! takes two arguments.... The second argument is a query expression.... The query expression should contain any additional keys which should be re-read following the mutations (e.g. :todos/list).

By default, the additional keys trigger both a local and remote read, but the remote read is not at all what I want.

I currently have two uses cases where this is becoming a problem:

1) I create a new entity via transact! that sends a remote query to the server, when the response comes, update the list of those entities with the newly-returned-from-the-server entity. However, since I specify an additional read key on the transact, it's triggering a remote read along with it, which is reading all the entities from the server, in this case which is a huge waste.

2) On the app-state, I have a non query-root that has within it some local-only state and some remote state. The remote state can stay updated with the server, that's fine, but since it's not a query-root, it causes problems with running an-additional-read-key read on this key, because the remote response overwrites its entire app-state.

(om/transact! c `[(~'do-something ~m)
                  :marshmallows)

The :marshmallows root app-state key is not a query root, yet when it triggers a :remote query, the remote query sends stuff to the server, gets data back, and automatically updates the app-state with the new data and overwrites the :marshmallows app state because the remote doesn't return local-only data not found on the server. (I understand I can configure :merge, but that's not at all what I want to do and quite messy.)

I'm sure there's many more possible cases, but I wanted to write my concrete ones.


For a solution, you can think up your own, as you wish, but it seems to me that a simple vector with remotes seems like a nice, clean, and more configurable alternative:

(om/transact! c `[(~'create-entity ~m)
                  [:entity :with :some :remotes])

Everything after the first key in the vector should be remotes, it would always run the local read, but the default would be only a local read.

matthavener commented 6 years ago

I think this is the intention of the force function