I don't think this is a bug. When you deref a cursor, you get the values stored in the underlying app-state atom. Here, you're storing a cursor in a component's local state. When you deref it later, you're still only going to get the values stored the the cursor's underlying app-state atom...
A couple things: 1) Storing cursors in local state is an anti-pattern. It's one of the few patterns that we've seen clear guidance on, which is: don't do it. 2) In case this isn't clear: after you "decorate" a cursor with assoc, it's still a cursor (with some extra stuff tagging along). We can verify this with the "type" function: https://www.refheap.com/92913 That refheap also shows one of your options, which is to use om/value (like deref, but intended for use during the render phase) to convert your cursor to values, so that instead of storing a cursor in local state, you're storing values. That would be better, but I still don't like it. You may be planning to update your application state in your event handler with om/transact! or om/update!, but those functions take cursors. So if you've already converted your cursor to values, you won't be able to use those functions. You would have to update app-state with another approach (callback, channel, or ref-cursor). Also, remember the primary goal of react: to minimize the complexity of managing state: http://facebook.github.io/react/docs/thinking-in-react.html "Figure out what the absolute minimal representation of the state of your application needs to be and compute everything else you need on-demand." In this case, you're taking data that's already stored in app-state, and storing it again in local state. I think you want to try avoid this wherever possible. Here's one possible approach that doesn't use local state at all: https://www.refheap.com/92914 HTH On Saturday, November 8, 2014 7:44:51 AM UTC-6, Colin Yates wrote: > Hi, > > I have found a bug, but it may well be (almost certainly is) in my > understanding ;). > > tldr; I decorate something from app-state and store as component-state. In > rendering I see the decorated thing but in on-click when I resolve the cursor > I see the undecorated thing. > > I have a hierarchy in my app-state and a tree-component to render it. The > tree component denormalises the tree so each node has an array of its > parent's ids and descendant ids (for example). I then persist this > decorated-tree as component state. > > The problem is that when I reference the decorated tree in the on-click, I > can see the cursor has access to the decorated tree but when I denormalise it > I see the undecorated tree. > > (As an aside, I originally tried it without component state and passed the > decorated tree as app-state to the delegate component but that exhibited the > same behaviour). > > I am sure I have missed something, but I don't see what - is this a bug in > om? I can by-pass this by simply storing everything in app-state in the > denormalised view, but that is not ideal - different components want to > render the same domain chunk differently (e.g. another component might show > this tree as a flattened list). > > The following code demonstrates the behaviour: > > [code] > (defn the-component > [_ owner] > (reify > om/IDisplayName > (display-name [_] "Component") > om/IRenderState > (render-state [_ {:keys [node]}] > (let [{:keys [id text children meta]} node] > (js/console.log "NODE in rendering contains meta:" > (clj->js (keys node))) > (html > [:li > {:key id > :on-click > (fn [e] > ;; prevent selection of the parent > (. e stopPropagation) > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > ;; the cursor node contains the "meta" key if you expand > ;; into .value.root.arr[2] > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > (js/console.log "(cursor)NODE in on-click (check > .value.root.arr[2]):") > (js/console.log node) > > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > ;; however it has all gone pear shape here... > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > (js/console.log "(deref)NODE in on-click no longer has 'meta':" > (clj->js (keys @node))))} > "Click me"]))))) > > (defn tree > [{:keys [node] :as data} owner] > (reify > om/IDisplayName > (display-name [_] "Tree") > om/IInitState > (init-state [_] > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > ;; decorate the value of the cursor from app-state > ;; but store locally > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > {:node (assoc node :meta {})}) > om/IRenderState > (render-state [_ {:keys [node]}] > (om/build > the-component > nil > {:init-state {:node node}})))) > [/code] > > (any and all comments welcome!) > > Thanks. -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/clojurescript.
