Skip to content

Instantly share code, notes, and snippets.

@bbktsk
Created June 19, 2017 14:40
Show Gist options
  • Save bbktsk/214e981c72df70f1f2e965575aaa4469 to your computer and use it in GitHub Desktop.
Save bbktsk/214e981c72df70f1f2e965575aaa4469 to your computer and use it in GitHub Desktop.
(ns wmcng.fake
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [clojure.string :as str]
[om.dom :as dom]
[om.next :as om :refer-macros [defui]]
[untangled.client.core :as uc]
[untangled.client.data-fetch :as df]
[untangled.client.logging :as log]
[untangled.client.mutations :refer [defmutation]]
[untangled.client.network :as net]))
(defui ^:once Car
static om/IQuery
(query [this] [::type ::color])
static om/Ident
(ident [this props]
[::car-by-type (::type props)])
Object
(render [this]
(let [{:keys [::type ::color]} (om/props this)]
(dom/div nil (str "type:" type ", color: " color)))))
(defui ^:once Person
static uc/InitialAppState
(initial-state [this props]
props)
static om/IQuery
(query [this] [::id ::name
{::car (om/get-query Car)} ])
static om/Ident
(ident [this props] [::person-by-id (::id props)])
Object
(render [this]
(let [{:keys [::id ::name ::car]} (om/props this)]
(println "Rendering person " id)
(dom/li nil
(dom/span nil (str id ": " name ", car "))
(if car ((om/factory Car) car) "(car not loaded)")
(dom/button #js {:onClick #(om/transact! this `[(load-car {:id ~id})])}
"Load car") ))))
(def person (om/factory Person {:keyfn ::id}))
(defui ^:once People
static uc/InitialAppState
(initial-state [this props]
{::people []})
static om/IQuery
(query [this] [{[::people '_] (om/get-query Person)}])
static om/Ident
(ident [this props] [::people :root])
Object
(render [this]
(println "Rendering people")
(let [{:keys [::people]} (om/props this)]
(dom/div nil
(if (seq people)
(dom/ul nil (map person people))
(dom/p nil "No people loaded"))
(dom/button #js {:onClick #(om/transact! this `[(initial-load)])} "Initial load")
(dom/button #js {:onClick #(om/transact! this `[(dumpstate)])} "Dump State")))))
(defmutation initial-load
"Initial load of data. Since the corresponding API endpoint does not return ::car, remove it from the query."
[params]
(action [{:keys [state] :as env}]
(df/load-action state ::people Person {:remote :remote
:without #{::car}}))
(remote [{:keys [state] :as env}]
(df/remote-load env)))
(defn log-state [tag state]
(println "=== " tag)
(println "STATE:")
(prn @state)
(println "DB->TREE")
(prn (om/db->tree (om/get-query People) {} @state)))
(defmutation load-car
"Load car for person specified by the ident."
[{:keys [id]}]
(action [{:keys [state] :as env}]
(println "loading car for " id)
(df/load-field-action state Person [::person-by-id id] ::car
:remote :remote
:marker false
;; !!! Without this, the display does not refresh after load.
:refresh [::people]
))
(remote [{:keys [state] :as env}]
(df/remote-load env)))
(defmutation dumpstate
[params]
(action [{:keys [state]}]
(log-state "BUTTON" state)))
(defn fake-remote-api [endpoint param]
(condp = endpoint
;; For the initial load, return just Person data
::people {::people [{::id 1 ::name "Adam", ::car nil}
{::id 2 ::name "Ben", ::car nil}]}
;; this is actually a request for the ::car field of the Person, so return just that
::person-by-id {[::person-by-id param] {::id param
::car {::type (str "Car " param)
::color (str "Color " param)}}}))
(defrecord FakeRestRemote [url request-transform global-error-callback complete-app transit-handlers]
net/NetworkBehavior
(serialize-requests? [this] true)
net/UntangledNetwork
(send [this edn ok-fn error-fn]
(let [ast (om/query->ast edn)
{:keys [key dispatch-key]} (get-in ast [:children 0])
result (fake-remote-api dispatch-key (if (vector? key) (second key) nil))]
;; Pretend we talk over network
(js/setTimeout #(do (println "req done, calling callback") (ok-fn result)) 500)))
(start [this app]))
(defonce app (atom (uc/new-untangled-client :networking (map->FakeRestRemote {}))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment