This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-06-07
Channels
- # aleph (19)
- # aws (1)
- # beginners (75)
- # boot (28)
- # cider (1)
- # cljs-dev (12)
- # cljsrn (20)
- # clojure (350)
- # clojure-argentina (1)
- # clojure-chicago (2)
- # clojure-dev (2)
- # clojure-russia (5)
- # clojure-spec (2)
- # clojure-uk (14)
- # clojure-ukraine (3)
- # clojurescript (68)
- # component (87)
- # core-async (25)
- # core-logic (13)
- # cursive (4)
- # data-science (72)
- # datascript (59)
- # datomic (15)
- # defnpodcast (7)
- # emacs (33)
- # hoplon (5)
- # immutant (73)
- # jobs (21)
- # klipse (6)
- # lumo (14)
- # off-topic (26)
- # om (23)
- # onyx (6)
- # parinfer (37)
- # protorepl (4)
- # re-frame (13)
- # ring (2)
- # rum (3)
- # spacemacs (2)
- # specter (22)
- # sql (47)
- # uncomplicate (10)
- # unrepl (79)
- # untangled (66)
- # vim (47)
- # yada (17)
ok, so what (df/load app :key Comp)
does is ship some EDN off the server that looks like {:key (om/get-query Comp)}
. the server then sends back a vector of things. untangled does #(swap! app-state assoc-in (ident Comp %) %)
for every element in this vector, and it also puts (map %(ident Comp %) result)
into :key
at the top-level of the app-state
On initial load, on the server, 1) generate the db with get-initial-app 2) set the current route 3) populate the db with the server data 4) render-to-str the app 5) dump the db in the html 6) client loads the pre-populated db from the html
(def app-state (uc/get-initial-state ui/Root {}))
(def parser (om-server/parser {:read api/api-read :mutate api/api-mutate}))
(def ui-parser (om-next/parser {:read plumbing/read-local :mutate plumbing/write-entry-point}))
(def reconciler (om-next/reconciler {:state (atom app-state)
:send (fn [d cb] (cb (parser {} (:remote d))))
:parser ui-parser}))
(df/load reconciler :all-items ui-root)
(def app-str (dom/render-to-str (ui-root app-state)))
Also noticed that new-untangled-client ignores the :initial-state
if the root component has uc/InitialAppState
is there any change this will change in the future ? To If I specify it then it will be used ?
@adamvh Untangled doesn’t do normalization. Om does. Untangled merges the result from the server using Om’s merge (which in turn uses the original query, which contains component metadata, to normalize the return value). The return value can be a vector or a singleton…up to the server.
If you look at the metadata on the query, you’ll see that get-query
hangs the component on the node of the query that was generated by that component. This allows tree->db
to figure out (recursively) which components to use to normalize the entire tree of data from the server into the UI database.
@claudiu Yes. You’re on the server. There is nothing to load. You’re doing server-side pre-rendering, not running the entire app there.
well, regardless of which layer of the stack is doing what, i think i understand what's happening, at least in the simple case of the dev-guide, so thanks for your patience and the nice video! 🙂
@claudiu You could generate a data structure and emit that into the page as embedded javascript and do some magic to merge that in…but as far as I’m concerned Untangled is not meant to be run on the server this way…just initial render. You have to wait for the JS to load before anything happens. If you know something in advance on the server you could technically embed it into initial-state
to get an initial render that looks pre-filled.
if the server doesn't know how to respond in EDN, is there somewhere i can hook into the df
mutations to EDN-ize whatever it gives me?
@claudiu The initial-state behavior is for bw compat. Once you embed it in a component, it overrides the option and issues a warning. But you can put logic in the initial-state
function of your root component.
@adamvh There are a couple of approaches. The EDN layer is at the networking. You can plug in a custom network object into client and do what you want with the EDN of the client and the responses of the server.
You could also just add functions to the server layer to speak to your app, since they are usually pretty thin
Also note that you can specify “which” remote, and can have more than one networking object installed
yea, that seems like the cleanest way to do that. where would i look for info on network objects and hooking them for different remotes?
if you’re using defmutation
:
(defmutation update-thing [{:keys [param]}]
(action [{:keys [state]}] ...local update...)
(name-of-remote-1 [env] ...stuff to send to remote-1...)
(name-of-remote-2 [env] ...stuff to send to remote-2...)
...)
in the network
namespce there is an UntangledNetwork protocol. Implement that. Mainly send
you’ll receive the data to send, and the callback to call with the response. EDN for both. You’re responsible for talking to the server however you want, and translating the response back to EDN that makes sense for merge.
for loads, load
supports a :remote
option that is just the name you choose for the remote
yea, will check it out. btw, if i take the time to figure out some of this stuff for myself and write up my understanding, is there some doc for which pull requests would be welcome?
Docs: the dev guide should have something on advanced networking already…welcome to add to it
the J section is also using df/load-data
in the exercises and solutions - given that i just worked through that, i was thinking i might update the solutions to use df/load-data
and the solutions don't refresh on load from the server (you have to type in the text box to trigger re-render)
I may have already made some fixes…you’d want to open an issue and point to the problems so I can look
@tony.kay thank you. Will play around with it a but more and see if I can find a way to reuse the code and populate the db. There were some render cobditionals in the df/load and though maybe there is a easy built in way. :)
yeah, how would I implemnent load
on the server? The networking is totally different.
Think while playing with om-next managed to get it working with reconciled :send
on the client it was a http call, on the server it was a call to the server parser directly. Was just a simple get from atom test so not sure if it has any gotchas.
I see. Calling the server parser directly in the initial-state
should work. all you need is a tree of data there
Will play around with it more. It’s a important for my project since i have a few public pages and it really helps with seo & loadtime.