Skip to content

Instantly share code, notes, and snippets.

@dariooddenino
Last active October 4, 2015 10:51
Show Gist options
  • Save dariooddenino/c70f77e7d3d8604321e5 to your computer and use it in GitHub Desktop.
Save dariooddenino/c70f77e7d3d8604321e5 to your computer and use it in GitHub Desktop.
Fetching JSONs and handling them in ClojureScript / Om
; A modified group-by for jsons.
; Eg. [{:id "id1" :title "one"} {:id "id2" :title "two"}]
; to, for example, this: {:id1 {:id "id1 :title "one"} :id2 {:id "id2" :title "two"}}
(defn group-json
[f coll]
(persistent!
(reduce
(fn [ret x]
(let [k (keyword (f x))]
(assoc! ret k x)))
(transient {}) coll)))
; Get the data with cljs-ajax and update the ref-cursor.
(defn get-results
[cursor limit skip]
(GET MY_URL {:params {:limit limit :skip skip}
:keywords? true
:response-format :json
:handler (fn [results]
(when-not (empty? results)
(om/transact! (cursor)
(fn [curs]
(merge curs (group-json :id results))))))))
; An app state cursor and a ref cursor used by our component.
(defonce app-state
(atom {:stuff {...} :other-stuff {...} :results {}}))
(defn results []
(om/ref-cursor (:results (om/root-cursor app-state))))
; The Om component that renders the elements (using sablono).
(defn first-view [_ owner]
(reify
om/IRender
(render [_]
(let [xs (om/observe owner (results))]
(html
[:div {}
[:ul {}
(for [[k v] xs]
[:li {} (:title v)])]])))))
; Another component that triggers the query.
(defn second-view [_ owner]
(reify
om/IRender
(render [_]
(html
[:div {}
[:input {:ref "limit" :id "limit" :placeholder "Limit"}]
[:input {:ref "skip" :id "skip :placeholder "Skip}]
[:button {:onClick (fn [_]
(let [limit (om/get-node owner "limit")
skip (om/get-node owner "skip")]
(get-results results (.-value limit) (.-value skip))))
"Fetch results"]
(om/build first-view)]))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment