Fork me on GitHub
#om-next
<
2017-11-17
>
dyba17:11:29

I have some data that I’ve fetched from the server, but it’s not in the format that I want to store it in the global atom. How would I go about modifying the response and storing it in the correct location in the atom? I’ve been considering adding a :merge option to my reconciler configuration. At this point, I’m reading the source code to figure out how this works and I’m at a loss for what to put in :tempids.

sova-soars-the-sora17:11:53

@daniel.dyba welcome! om next is really great. i recommend asking your question in the #om channel or even in the #clojurescript channel. I have code that figures out where things live in the clientside/js/browser atom and slides them on in. let me see if I can find an example for you my good man.

dyba17:11:53

@sova thanks! do the #om and #clojurescript channels have more activity?

dyba17:11:03

I figured I’d choose this channel because it’s om-next specific

sova-soars-the-sora17:11:43

#om has more activity this #om-next channel is not really where discussions go down (david nolen creator of om and om.next and antonio [co-maintainer] spend their time in #om

dyba17:11:09

ah, thanks for the tip! @sova

sova-soars-the-sora17:11:17

So I had to ask for help writing a merge function for the local atom...

sova-soars-the-sora17:11:29

@joshjones hooked me up with a great chunk of code 😃

sova-soars-the-sora17:11:00

I'll paste you what I have, it has been catered to my specific situation

dyba17:11:35

the last time I tried writing a custom merge function, I found myself in an infinite loop 😕

dyba17:11:44

it kept re-rendering the components

sova-soars-the-sora17:11:16

So you can click to expand that snippet.

sova-soars-the-sora17:11:52

Hmm this is more for updating an existing (nested) set of atom values [some of my items have "ratings" and there's one "active blurb" that has its own ID.

dyba17:11:29

@sova which one is the custom merge function? Neither seems to have the correct number of arguments

sova-soars-the-sora17:11:37

Anyway, I don't want to confuse you, there are experts that can help in #om for sure, but you can see that this snippet uses merge. you may have to use merge-with sometimes as to not overwrite the existing atom with just 1 entry

sova-soars-the-sora17:11:41

Okay well, tell me more about your data

sova-soars-the-sora17:11:45

So you get some entries from the server, you want to insert them into the atom in the right place, yar?

sova-soars-the-sora17:11:16

well this function actually uses assoc

sova-soars-the-sora17:11:30

and a lot of my functions to add into the atom use assoc-in

dyba17:11:22

Line 2355 pulls the custom merge function I specify when I create my reconciler and then my custom merge gets called on Line 2356

dyba17:11:42

It requires that I return a map with :keys, :next, and :tempids. I know what to put in :keys and :next but not :tempids

sova-soars-the-sora17:11:37

Ah you are updating the whole atom with a delta and a merge function to handle it. Cool. Mmm, you need to have tempids... I'm gonna say: ask in the #om channel, I think there is a placeholder function but i'm not sure. Your database could push tempids across the wire with the data update, but again someone more experienced in #om will be able to set you straight faster

sova-soars-the-sora17:11:29

@daniel.dyba for all my inserts into the atom I use a specific mutate function for each attribute branch in the atom.... Have you tried just using an underscore for tempids ?

dyba17:11:54

@sova I thought underscores only work when you’re destructuring. Are you suggesting using an underscore as a return value?

sova-soars-the-sora17:11:54

destructuring yes, not as a return.

dyba17:11:06

@sova I copied my question to the #om channel too

dyba17:11:31

@sova Right, but Line 2356 expects a return value for :tempids

sova-soars-the-sora17:11:01

oh good. yeah they might take a little while but the experts live there. hmm so can you show me the way you're invoking this, maybe I can help more

dyba17:11:02

you can’t use destructuring at this point

sova-soars-the-sora17:11:00

So you have a remote specified, and therefore it is trying to get your tempids

dyba17:11:04

clojure
;; where on is a reference to om.next
  (def reconciler (on/reconciler
                   {:state m/init-data
                    :parser parser
                    :send (m/send-to-chan send-chan)
                                        ; FIXME: We're missing a merge function that does a custom merge on the data
                                        ; we get back from the server
                    :merge (fn [reconciler state delta query]
                             {:keys []
                              :next state
                              :query nil})
                    ; it should return a map with the keys: :keys, :next, :tempids
                    ; what's the purpose of tempids???
                    :remotes [:list-models]}))

dyba17:11:10

there’s more code to this obviously, but this is the heart of the matter

sova-soars-the-sora17:11:46

i think you can just generate some tempids for this specific task, they don't need to be anything special .. i think the way this is normally done is with [in your case] on/tempid

sova-soars-the-sora17:11:57

because it needs a fake index as it's moving them from the database into the atom, is my understanding.

dyba17:11:12

Right, but do I generate one? Do I generate the number equivalent to the count of the list I get back from the server? And what data structure is tempids?

dyba17:11:36

Suppose the response from the server is:

{
  "model": {
    "items": [
      "A",
      "B",
      "C"
    ]
  }
}

dyba17:11:44

Then that response is captured here:

(defn model-list-loop
  [c]
  (go-loop [cb (<! c)]
    (let [results (<! (reg/list-models))]
      (cb {:list/model-names (get-in results [:model :items])}))
    (recur (<! c))))

dyba17:11:01

Where results is the map that represents the above server response

sova-soars-the-sora17:11:31

and you're looping over all your remotes there?

dyba17:11:35

model-list-loop is called immediately after the reconciler is defined

sova-soars-the-sora17:11:52

Om.next has an internal representation for stuff in the atom, which is where I think tempids come in.

sova-soars-the-sora18:11:28

For every new transaction you need to have a tempid, but I don't know to be honest, i never used merge to update to the atom. except for those snippets i showed you. I think just one tempid per transaction (like the ones you see in the javascript console) is sufficient

sova-soars-the-sora18:11:42

you've probably seen this video but at around 19:43 he goes into tempids

sova-soars-the-sora18:11:27

anyway, good luck dude, sorry i couldn't be more help 🙂

dyba18:11:30

@sova thank you for taking the time to answer my questions!