0

I am having problems with updating state with data from input fields in Om.next.

Reading state in Om.next is solved by queries and queries enable components to implement fetching state independent of context, which is great, as that means the component doesn't need to know the structure of the state atom, it just has to understand the local snippet of the state atom that pertains directly to it.

Unfortunately I haven't been able to determine a way to do this in the opposite direction, i.e. mutating state based on user's interaction with components in a way that doesn't couple it with the position of component in the state atom.

Most examples on the web have mutate functions that modify a particular path in the state atom, starting from the root.

(defonce app-state (atom {:badge {:credentials {:user "" :password ""}}}))

So now I go to render the component:

Object
(render [this]
(dom/div nil
       (dom/input #js {:onChange ???
                       :value {:user value}})
       (dom/input #js {:onChange ????
                       :value {:password value}})))

It's a rather crude example, but how do I update the state when user types, without coupling to the fact that it's stored under path [:badge :credentials]?

The reads are scoped by the query, but the mutations are not. This is a simple contrived example, but it gets worse when I try to render and update a nested tree with (at coding time) unknown shape.

Dijkgraaf
  • 11,049
  • 17
  • 42
  • 54
RokL
  • 2,663
  • 3
  • 22
  • 26

1 Answers1

0

Your :onChange could invoke one of your mutations:

:onChange (fn [_] (om/transact! this `[(app/set-name { :person 1 :name ~n })]))

Apart from the parameters, and the place where the mutation is called from, there is no coupling - the mutation is nothing but a name - here app/set-name. Of course the mutation has to be implemented. Here it is:

(defmethod m/mutate 'app/set-name
  [{:keys [state] :as env} key {:keys [person name] :as params}]
  {:action (fn []
    (swap! state update-in [:people/by-id person] assoc :person/name name))})

The mutation code itself will be dealing with normalized app-state, which means that the structural-shape of the data is not a tree.

This example was taken from: http://localhost:3449/#!/untangled_devguide.G_Mutation

Chris Murphy
  • 6,411
  • 1
  • 24
  • 42