Fork me on GitHub
#om
<
2017-02-24
>
petterik01:02:07

@devth I don't know about a map you'd get from the request that would tell you which set of reads/mutations that would be fired. You could run the query through a separate parser to determine this set client or server-side. Something like:

(let [parser (om/parser {:read   (constantly {:value 1}) 
                         :mutate (constantly {:action (constantly 1)})})
      query [(list 'mutate/this) :read/that]] 
  (set (keys (parser {} query))))

petterik01:02:33

#{:read/that mutate/this}

qqq05:02:20

What is the interplay between om/Ident and om/IQuery ? I appear to have a situation where the existing of an om/Ident field changes the way an IQuery is being run.

alex-glv05:02:58

om.next + datomic = ❤️ … It was one clever decision to match the query language with datomic pull, the combination is really powerful.

bbss05:02:48

@alex-glv have you been using it?

alex-glv05:02:48

Just working on a small personal project. Similar to trello, with oauth. It took a long while to get up to speed with so many new concepts (and om.next docs are far from great at this point) but matching server/front-end together in read/mutate decoupling is really an interesting approach.

bbss05:02:03

this is one of the best resources on it I've found: https://github.com/madvas/todomvc-omnext-datomic-datascript

bbss05:02:34

haha, that's funny, I did a similar thing before github introduced kanban view I was working on a chrome extension doing exactly that, also using om next 🙂

bbss05:02:13

cool, thanks

alex-glv05:02:06

Neither implement routing, though, so that was a bit tricky to grasp. Again, om provides enough primitives to implement it all, it just feels a bit cumbersome at this point.

alex-glv05:02:56

Yeah, I think “what’s the trivial thing I can implement with my new shiny stack?” almost begs for a trello clone 🙂

bbss05:02:45

yeah, filtering and querying made easy

qqq05:02:51

where is a set of exercises I can work through to understand the interplay of om/IQuery and om/Ident ? If I have an object and it only uses om/IQuery, everything works fine; however, when I add an om/Ident field to it, it seems to do weird things (via normalization?) to the data I'm sending to it, and I no longer understand what is going on

bbss05:02:28

@qqq have some trouble fully understanding it as well but as for excersises:

bbss05:02:38

further the guide helps as well

qqq05:02:22

@bbss: I worked through those last night (but was discussing it in the #untangled channel), unfortunately, it's about definig data, not the interaction of Ident/IQuery

bbss05:02:47

right, just closest thing I know that might enlighten 🙂

bbss05:02:55

guess you'll have to dive into the source!

qqq06:02:57

(def hello (om/factory HelloWorld))

(js/ReactDOM.render
  (hello {:title "Hello, World!"})
  (gdom/getElement "app")
)
now, I have devcards and devcards-om-next installed. How can I pass props via: defcard, om-next-root, and defcard-om-next ?

qqq06:02:23

In the following block of code:

(ns om-tutorial.core
  (:require [goog.dom :as gdom]
            [om.next :as om :refer-macros [defui]]
            [om.dom :as dom]))

(def app-state (atom {:count 0}))

(defn read [{:keys [state] :as env} key params]
  (let [st @state]
    (if-let [[_ value] (find st key)]
      {:value value}
      {:value :not-found})))

(defn mutate [{:keys [state] :as env} key params]
  (if (= 'increment key)
    {:value {:keys [:count]}
     :action #(swap! state update-in [:count] inc)}
    {:value :not-found}))

(defui Counter
  static om/IQuery
  (query [this]
    [:count])
  Object
  (render [this]
    (let [{:keys [count]} (om/props this)]
      (dom/div nil
        (dom/span nil (str "Count: " count))
        (dom/button
          #js {:onClick
               (fn [e] (om/transact! this '[(increment)]))}
          "Click me!")))))

(def reconciler
  (om/reconciler
    {:state app-state
     :parser (om/parser {:read read :mutate mutate})}))

(om/add-root! reconciler
  Counter (gdom/getElement "app"))
why does the mutate function include a :value {:keys [:count]} then the :action part already has the [:count] encoded ?

bbss06:02:22

seems hard to statically analyze the action function for finding out what changed

bbss06:02:54

also not sure you want om to respond to every state change made in action

qqq06:02:22

so suppose I did :value wrong -- i.e. I updated :foo and :bar, but I only had :value {:keys [:foo]} does this mean there are things that depend on :bar that won't be updated?

qqq06:02:36

i.e. is it programmer / my responsibility to enumerate everything that could change? this seems error prone

bbss06:02:30

Hmm, :thinking_face: I'm not sure of this, so someone please correct me if I'm wrong. But yeah, not gonna re-render parts that use :bar if :foo isn't also in the read.

qqq08:02:03

how do I embed initial data (if none present) into the om root element? I searched through https://github.com/omcljs/om/wiki/Quick-Start-(om.next) for "init" but couldn't find it -- but could have almost sworn that I used it somewhere

bbss08:02:29

you can pass it to the element directly as an argument to the component ((om/factory UiComponent) {props "stuff")

bbss08:02:00

when using reconciler you could pass it to :state

qqq08:02:15

there's no om/InitialState that I can inherit and then implement a (initial-state [] ... ) ?

qqq08:02:28

I could have sworn I used something like that to specify initial state, but I can't find it anymore

bbss09:02:22

there is initialState but it's a react thing

bbss09:02:35

like so:

Object
 (initLocalState [this]   
   {:state-count 0})
  (componentWillUnmount [this]
    (println "Buh-bye!"))

hlolli09:02:57

the :value in mutate is a no-op

qqq09:02:44

really basic question: why should I use om/transact! instead of swap!

baptiste-from-paris09:02:41

@bbss the todo app is a good example,

bbss10:02:11

@baptiste-from-paris Yeah, @madvas did a great job on that one

hlolli10:02:23

transact can retrigger reads swap doesnt, probably more losses of swapping, you should never need to swap! even tough swap! may at time deliver the result you are looking for.

qqq10:02:03

ah, I see, "swap!" is a blackbox in terms of "what was updated", but trnasact! with queries, makes it statically analyzeable what was updated

hlolli10:02:09

maybe you loose too the reconciler history, well you probably do. You can swap, if you're looking for this simple architecture for rendering you may want to check out re-agent.

qqq10:02:11

and this allows om to know which elems need to be updated?

hlolli10:02:59

yes, the components aren't dereferncing the app-state, except needed/asked for trough the parser.

hlolli10:02:16

which makes om fast I guess.

qqq10:02:44

okay, so swap! is useful only in tutorals that walk you through the basics

qqq10:02:01

after going through tutorials, I should pretty much never use swap! (unless in exceptional cases) and basically always use om/transact! ?

hlolli10:02:08

yes, get in the habit of using transact. You can make the overhead of transact! more concice with some macros, in untangled there's defmutation macro. But to be sure we are on the same level, in the parser you can swap as much as you want.

hlolli10:02:16

but don't mutate some values that the mutation wont retrigger read of 🙂

baptiste-from-paris10:02:29

@bbss I am wondering how much the cljc can grow since he abstract datomic datastrictdepending on the platform

bbss10:02:26

yeah it's cool stuff. Actual useful code sharing between platforms 🙂

dnolen18:02:28

@anmonteiro which PRs did you want me to look at?

anmonteiro18:02:34

@dnolen OK to cut a release too?

anmonteiro18:02:05

(excuse me if you were already doing it)

anmonteiro18:02:34

awesome, looking forward to it

anmonteiro23:02:39

@dnolen the new ClojureScript release broke Om Next 🙂

anmonteiro23:02:49

we use cljs.core/js-arguments which is now private

dnolen23:02:37

hrm that one probably shouldn’t have been private

anmonteiro23:02:19

in Mike’s defense, it says ;; internal - do not use

dnolen23:02:48

yeah I probably should have looked more closely at that patch

anmonteiro23:02:28

hrm, I’m thinking all the macros marked internal shouldn’t be private

anmonteiro23:02:32

like coercive-not etc

dnolen23:02:33

will fix tomorrow and recut

dnolen23:02:42

most of those macros should be public

dnolen23:02:48

people will need them in interop cases