Skip to content

Instantly share code, notes, and snippets.

@kshahkshah
Last active June 5, 2016 22:15
Show Gist options
  • Save kshahkshah/c003125f605bbfae6dadb6ec3ca630a2 to your computer and use it in GitHub Desktop.
Save kshahkshah/c003125f605bbfae6dadb6ec3ca630a2 to your computer and use it in GitHub Desktop.
(ns foo-cart.core
(:require [goog.dom :as gdom]
[om.next :as om :refer-macros [defui]]
[om.dom :as dom]
[cljs.pprint :as pp]))
(enable-console-print!)
(defmulti read om/dispatch)
(defmulti mutate om/dispatch)
(defmethod read :products
[{:keys [query state]} k _]
(let [st @state]
{:value (om/db->tree query (get st k) st)}))
(defmethod read :cart
[{:keys [query state]} k _]
(let [st @state]
{:value (om/db->tree query (get st k) st)}))
(defmethod read :default
[{:keys [state]} k _]
(let [st @state]
(if (contains? st k)
{:value (get st k)}
{:remote true})))
; this is for my old style... won't work, but, just want to get
; this rendering right and I fix the mutation function later.
(defmethod mutate 'cart/add
[{:keys [state]} _ {:keys [id]}]
{:action
(fn []
(swap! state update-in
[:cart id]
(fn [m] (if (nil? m)
{:id id :count 1 :product [:product/by-id id]}
(update m :count inc)))))})
(def init-data {:products [
{
:id 1
:name "Foo"
:image "image1.jpg"
:price 1
:inBulk {
:amount 4
:totalPrice 0.75
}
}
{
:id 2
:name "Bar"
:image "image2.jpg"
:price 2
:inBulk nil
}
{
:id 3
:name "Baz"
:image "image3.jpg"
:price 1.25
:inBulk {
:amount 4
:totalPrice 5
}
}
{
:id 4
:name "Woz"
:image "image4.jpg"
:price 3
:inBulk nil
}
]
:cart [{:id 1 :count 2 :product [:product/by-id 1]}]})
(defui Product
static om/Ident
(ident [_ {:keys [id]}]
[:product/by-id id])
static om/IQuery
(query [this]
'[:id :name :image :price])
Object
(render [this]
(let [{:keys [name image price id] :as props} (om/props this)]
(dom/div #js {:react-key id :className "product"}
(dom/img
#js {:className "product-image"
:src image
:alt (str "image of" name)
}
nil)
(dom/div #js {:className "product-info"}
(dom/strong #js {:className "product-name"} name)
(dom/span #js {:className "product-price"} (str "$" price nil))
(dom/button
#js {:className "product-action"
:onClick (fn [e] (om/transact! this `[(cart/add ~props) :cart]))}
"Add to Cart"))))))
(defui CartItem
static om/Ident
(ident [_ {:keys [id]}]
[:cart/by-id id])
static om/IQuery
(query [this]
[:id :count {:product (om/get-query Product)}])
Object
(render [this]
(let [{:keys [id count product] :as props} (om/props this)]
(dom/div
#js {:react-key (str "cart-item-" id)}
(dom/div nil (str product))
(dom/div nil (str "Count: " (get (om/props this) :count)))
))))
(def product (om/factory Product {:keyfn :id}))
(def cart_item (om/factory CartItem {:keyfn :id}))
(defui RootView
static om/IQuery
(query [_]
[{:products (om/get-query Product)} {:cart (om/get-query CartItem)}])
Object
(render [this]
(dom/div nil
(dom/h1 nil "The Foo Shop")
(dom/div #js {:id "products"} (map product (get (om/props this) :products)))
(dom/div #js {:id "cart"} (map cart_item (get (om/props this) :cart))))))
(om/get-query CartItem)
(def parser (om/parser {:read read :mutate mutate}))
(def reconciler (om/reconciler {:state init-data :parser parser}))
(om/add-root! reconciler RootView (gdom/getElement "app"))
(pp/pprint @reconciler)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment