Why is the counter in the child component updating fine when I comment
(om/update-state! owner :clicked not)
and not when I uncomment it in the parent component in the code below? The counter is updated by clicking the button.
What I'm trying to accomplish is a pub/sub mechanism so components can exchange messages in a decoupled fashion.
You can replicate it by making a new project with:
lein new mies-om om-channel-test
Then replace core.cljs with code below and run
lein cljsbuild auto
Visit the index.html page in a modern browser (for example the latest Chrome).
The code:
(ns om-channel-test.core
(:require-macros [cljs.core.async.macros :refer (go)])
(:require [om.core :as om :include-macros true]
[om.dom :as dom :include-macros true]
[cljs.core.async :refer [chan pub <! sub >! timeout put!]]))
(enable-console-print!)
(def app-state (atom {:text "Hello world!"}))
(def event-ch (chan))
(def event-pub
(pub event-ch #(:topic %)))
(defn child [cursor owner]
(reify
om/IInitState
(init-state [_]
{:counter 0})
om/IWillMount
(will-mount [_]
(go (loop [] (<! (om/get-state owner :subscriber))
(println "message received")
(om/update-state! owner :counter inc)
(recur))))
om/IRender
(render [_]
(println "rendering child")
(dom/p nil (om/get-state owner :counter)))
om/IWillUnmount
(will-unmount [_]
(println "unmount"))))
(defn parent [cursor owner]
(om/component
(println "rendering parent")
(dom/div nil
(dom/button #js {:onClick
#(do
#_(om/update-state! owner :clicked not)
(go (>! event-ch {:topic :wizard
:message "hello"})))}
"Click")
(om/build child
cursor
{:init-state
{:subscriber
((om/get-shared owner :create-subscriber) :wizard)}}))))
(om/root
parent
app-state
{:target (. js/document (getElementById "app"))
:shared {:create-subscriber (fn [topic]
(sub event-pub
topic (chan)))
:event-ch event-ch}})