Skip to content

Instantly share code, notes, and snippets.

@petterik
Created May 17, 2017 19:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petterik/0858c903d470be1245314c9b640a00c5 to your computer and use it in GitHub Desktop.
Save petterik/0858c903d470be1245314c9b640a00c5 to your computer and use it in GitHub Desktop.
om.next transform-reads issue
;; Issue with om/transform-reads
;; Issue is when having two siblings or cousins with the same read-key
;; in nested at level 2 or deeper, transform-reads will two paths
;; with the same root. Parsing such query will overwrite the first path
;; returning only the second one.
;; Example:
;; (om/transform-reads r [:foo])
;; returns: [#:join{:parent [#:join{:child1 [:foo]}]}
;; #:join{:parent [#:join{:child2 [:foo]}]}]
;; Parsing the query will return :foo only for the second path:
;; #:join{:parent #:join{:child2 {:foo 1}}}
;; Repro:
(require '[om.next :as om :refer [defui]])
(require '[om.dom :as dom])
;; Is it possible to repro without a render target? Doesn't seem like it.
(require '[goog.dom :as gdom])
(def render-target (gdom/getElement "app-div"))
(defui Child1
static om/IQuery
(query [this] [:foo])
;; ^^^^ important
Object
(render [this]
(dom/div nil "child1")))
(defui Child2
static om/IQuery
(query [this] [:foo])
;; ^^^^ important
Object
(render [this]
(dom/div nil "child2")))
(defui Parent
static om/IQuery
(query [this]
[{:join/child1 (om/get-query Child1)}
{:join/child2 (om/get-query Child2)}])
Object
(render [this]
(dom/div nil "parent"
((om/factory Child1) (:join/child1 (om/props this)))
((om/factory Child2) (:join/child2 (om/props this))))))
(defui Grandparent
static om/IQuery
(query [this] [{:join/parent (om/get-query Parent)}])
Object
(render [this]
(dom/div nil "grandparent"
((om/factory Parent) (:join/parent (om/props this))))))
;; Needs a read for repro.
(defn read [{:keys [parser query target state] :as env} k _]
(if (= "join" (namespace k))
{:value (parser env query target)}
{:value (get @state k)}))
(def r (om/reconciler {:state (atom {:foo 1}) :parser (om/parser {:read read})}))
(om/add-root! r Grandparent render-target)
(def foo-query (om/transform-reads r [:foo]))
(prn foo-query)
;; => [#:join{:parent [#:join{:child1 [:foo]}]} #:join{:parent [#:join{:child2 [:foo]}]}]
((-> r :config :parser) (#'om/to-env r) foo-query)
;; => #:join{:parent #:join{:child2 {:foo 1}}}
;; Missing out on the child1's query.
;; Query must be merged to get both.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment