Fork me on GitHub
#om
<
2016-05-28
>
pletcher02:05:22

(no rush on this — but I feel like I’m going crazy and could use a pointer or two when someone gets a chance) — is it normal to pull out the result of a remote mutation explicitly in the associated read? for example, there’s a remote function

(defmethod mutate ‘item/change
  [{:keys [ast state] :as env} _ _]
  {:action #(swap! state assoc-in [:item :loading] true)
   :remote ast
   :value {:keys [:item]}})
this goes through send, changes an item on the server, and then adds a {‘item/change {:result {…}} map to state. The only way I’ve found to merge in the changes in :result has been with the read method
(defmethod read :item
  [{:keys [query state] :as env} k _]
  (let [st @state]
    {:value (get-in st [‘item/change :result]
              {:id :temp
               :hearted false
               :link “img/default.jpg"
               :loading false})}))
but this feels wrong — there has to be a better way to merge in the changes from the server, right? I just can’t quite figure it out from the docs and examples that I’ve come across, but I’m probably missing something basic

iwankaramazow07:05:24

@pletcher: post-processing the response from the server, is kind of tricky atm. What you could be doing, is modifying the send function. When the send function has access to the reconciler, you can run mutations

iwankaramazow07:05:39

after the result has been merged back in

iwankaramazow07:05:51

to avoid circular dependencies between the send & reconciler, you'll have to write something like this:

iwankaramazow07:05:01

(defn make-reconciler
  [{:keys [state parser merge merge-tree migrate id-key]}]
  (let [escape-hatchet (atom nil)
        config {:state state
                :parser parser
                :migrate migrate
                :id-key id-key
                :merge merge
                :merge-tree merge-tree
                :send (transit-post "/api" (assoc {} :reconciler  escape-hatchet))}
        reconciler (om/reconciler config)]
    (reset! escape-hatchet reconciler)
    reconciler))

iwankaramazow07:05:24

Hmm, that being said. Send might be the wrong place to do post-processing stuff.

iwankaramazow07:05:46

Maybe, you'll need to modify the

(defn default-merge [reconciler state res query]
  {:keys    (into [] (remove symbol?) (keys res))
   :next    (merge-novelty! reconciler state res query)
   :tempids (->> (filter (comp symbol? first) res)
              (map (comp :tempids second))
              (reduce merge {}))})

iwankaramazow07:05:37

You'll have to find a system, where you stick mutations in the app-state & when the response arrives/has been merged, you can automatically run those mutations

pletcher11:05:25

Thanks, @iwankaramazow! I really like the second example. tempids still seem a bit magical to me, and I'm not quite sure how/where to use them (despite having read through a few examples); but changing the default merge feels a lot cleaner than what I've been doing. I'll play around with that

iwankaramazow13:05:17

@pletcher: tempids are only relevant if you create new data on the client, persist it on the server and want to swap that 'temporary' id on the client with the real id from the server

pletcher14:05:39

sweet, makes sense — thanks again! That seems intuitive now that you’ve worded it that way, but seeing it written out is very helpful 🙂

currentoor15:05:58

has anyone been able to extend bidi to support om tempids?

imaximix16:05:31

has anyone ran over "Encountered two children with the same key, .$undefined"? I'm trying to render two of my components, and om.next sets the key = "undefined" An obvious way to workaround is to give a key by myself.

selfsame16:05:11

@imaximix: yeah happens a lot, and yeah either give it a :keyfn in the factory opts or a :key attr for om.dom

iwankaramazow17:05:39

@currentoor: what do you mean by bidi supporting tempids?

currentoor17:05:16

@iwankaramazow: for example in a bidi route you can have [bidi/uuid:id] and it will automatically encoded and decode id’s for you

currentoor17:05:42

i believe it’s possible by extending their protocol, but i was just wondering if someone has done it already

iwankaramazow17:05:16

I don't think anyone has done that

iwankaramazow17:05:29

I implemented a router, let me check if tempids work in url

currentoor17:05:45

so then i could do something like [om/tempid :id]

iwankaramazow17:05:47

hmm just tried it out in, tempids in urls might take some extra work

iwankaramazow17:05:09

I mean (om/tempid) gives you #om/id["c62d156a-2a0c-4625-a29a-be93de888e99"]

iwankaramazow17:05:04

@currentoor: (subs (str (om/tempid)) 8 44) 😇

iwankaramazow17:05:31

works this way

iwankaramazow17:05:41

probably not the right solution though

iwankaramazow18:05:29

Given the current implementation, is there a way to take out the id as string?

tomjack20:05:47

^:mutable id wat

tomjack20:05:44

so (.-id tempid) should work, right?

tomjack20:05:50

the idea of a tempid in a URL seems kind of funny to me 🙂

ag23:05:56

can anyone help me to understand what I’m doing wrong? I’ve created simple repo to explain what I’m struggling with. Pretty please… https://github.com/agzam/om-basic-app

ag23:05:27

I cannot figure out how to dynamically change queries

ag23:05:56

so I have a join query in my root component:

[{:app/current-data ~(om/get-query UiContainer)}]
now when I’m trying to use set-query! on UiContainer and it doesn’t work

ag23:05:23

apparently I’m failing to understand how queries should be in all 3 places: - in App root - in UiContainer (query of which App root points to) - in set-query!