Fork me on GitHub
#fulcro
<
2017-10-12
>
tony.kay02:10:17

The reason is nested forms and rendering. Won’t work the other way. My original design in fact was that. You render and edit the real entity, and the forms support caches the pristine state. Think of it like a checkpoint: Start editing (init form) makes a copy of the real entity, then you’re optimistically updating it in-place, with the choice to commit those changes at any time (blur, submit, etc.)

Alister Lee08:10:08

@tony.kay brain slowly catching up... would the transact be between the ssr/build-initial-state and the fc/get-initial-state?

Alister Lee11:10:05

How do I call the server-side mutation from server code? is it with transact! somehow?

claudiu11:10:22

think the macros translate to a multimethod on the server also. but no idea where and how to call 🙂

fatihict14:10:14

@clojure388 You should be able to call it like any other multimethod. See: https://clojure.org/reference/multimethods

tony.kay16:10:05

@clojure388 what @fatihict said is true, but not necessarily the best approach. Functional composition is your friend. Write simple functions that can be used easily from SSR and your mutations is what I'd do. If you feel you want to directly use a mutation then you'll have to set up an env, invoke the multimethod, pull out the resulting :action key and run it. Mutations return a map describing what to do, they don't do it themselves.

tony.kay17:10:33

(let [action (get (fulcro.server/server-mutate env 'mutation-sym params) :action)] (action)) is roughly how to invoke a mutation

tony.kay21:10:32

@clojure388 I just realized you asked something more: get-initial-state pulls the tree from a component (assumed to be root for this purpose). build-initial-state turns it into a normalized db with union initial state set up. From there, you can use client-side coding techniques to update that db, including calling client-side code you’ve placed in cljc files. You could call the mutations (of the client) if you put that db into an atom an pretended to be the framework:

(let [tree (get-initial-state Root)
       state (atom (build-initial-state tree Root)
       run-mutation (fn [env sym params] ((:action (fulcro.client.mutations/mutate env sym params))))
       env {}]
   (run-mutation env 'mutation-a {:x 1})
   (run-mutation env 'mutation-b {:x 1})
   ...
   @state)

tony.kay21:10:23

Or anything else you want to do. If you’re following my coding guidelines from the Reference Guide, you’ve written helpers that can work on the state-map (not needing an atom or mutation invocation):

(-> (build-initial-state (get-initial-state Root nil) Root)
   (mutation-helper-a {:x 1})
   (mutation-helper-b {:x 1})
   ...)

tony.kay21:10:50

in terms of “loading data”, you just need to put it in the resulting app db just like you would via a mutation…just using the database data. For example:

(let [state (build-initial-state (get-initial-state Root nil) Root)
      entity (query-my-db 32)
       id (:id entity)
       the-ident [:entity/by-id id]]
   (-> state 
      (assoc-in ident entity)
      (assoc-in [:ui-thing/by-id :panel :current-entity] ident)))

tony.kay21:10:19

It’s always the same story: you’re building up the client database via a sequence of transforms. As helpers, they’re isomorphic for the client or server. Once you understand how to create the graph for your UI, you have the primary tool…it’s just tables and idents forming a graph. Do what ya gotta do to put it in the right shape. Pure rendering will result in your getting the right SSR result for that state.

tony.kay21:10:14

The only reason build-initial-state doesn’t get the tree for you is that it is possible you’d like to manipulate the tree for some reason before normalizing it…