Created
June 19, 2017 14:40
-
-
Save bbktsk/214e981c72df70f1f2e965575aaa4469 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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