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.

Reply via email to