Skip to content

Instantly share code, notes, and snippets.

@Jannis
Last active November 10, 2015 20:33
Show Gist options
  • Save Jannis/66ebbcd791ad9b6e24a4 to your computer and use it in GitHub Desktop.
Save Jannis/66ebbcd791ad9b6e24a4 to your computer and use it in GitHub Desktop.
Hack to bind Om Next transaction reads to a component
;; Function to resolve keys passed to an Om Next transaction to their corresponding
;; queries in the component that triggered the transaction. Ugly as hell. ;)
;;
;; (defui Foo
;; static om/IQuery
;; (query [this]
;; [:app/foo
;; {:app/bar (om/get-query Bar)}
;; ({:app/baz (om/get-query Baz)} {:param "Value"})])
;;
;; Calling:
;;
;; (txbind foo `[(foo/do-something) :app/foo :app/bar :app/baz])
;;
;; Results in:
;;
;; [(foo/do-something)
;; :app/foo
;; {:app/bar [:bar/id :bar/name]}
;; ({:app/baz [:baz/id :baz/other]} {:param "Value"})]
;;
;; Can be used like this inside the component:
;;
;; (om/transact! this (txbind this `[(foo/do-something) :app/foo :app/bar :app/baz]))
(defn txbind [c tx]
{:pre [(om/component? c) (vector? tx)]}
(letfn [(matches-read [q k]
(or (= q k)
(and (map? q) (contains? q k))
(and (seq? q) (= (first q) k))
(and (seq? q) (map? (first q)) (contains? (first q) k))))
(resolve-read [cq k]
(if (keyword? k)
(if (map? cq)
(if (matches-read cq k) cq k)
(let [matches (filter (fn [q] (matches-read q k)) cq)]
(case (count matches)
0 k
1 (first matches)
(throw (str "Ambiguous transaction read " k " in "
"component " c ". Matches: " matches)))))
k))]
(let [cq (om/get-query c)]
(into []
(map #(resolve-read cq %))
tx))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment