I see. Thanks again. 

On Saturday, 8 November 2014 16:56:09 UTC, jack james  wrote:
> I try to avoid these types of generalizations.  There's nothing inherently 
> wrong with "decorating" a cursor, and it will work fine in many scenarios.  
> But when you need app-state data + some other data in an event handler, 
> you'll need a different approach, because deref will only return the 
> underlying app-state values.
> 
> 
> On Saturday, November 8, 2014 10:39:49 AM UTC-6, Colin Yates wrote:
> > James, thank you. That does help.  My mental model of app-state being pure 
> > domain and view hierarchies effectively projecting their own structures is 
> > the thing to challenge.
> > 
> > The approach,  if I may generalise is by all means project off app-state 
> > but keep it alongside (e.g. through opts as you show), rather than 
> > intermingled with?
> > 
> > Essentially,  it all went wrong when I mutated the cursor itself.
> > 
> > Thanks James, 
> > 
> > Colin
> > 
> > On 8 Nov 2014 16:17, "jack james" <jack.jack...@gmail.com> wrote:
> > 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 a topic in the 
> > Google Groups "ClojureScript" group.
> > 
> > To unsubscribe from this topic, visit 
> > https://groups.google.com/d/topic/clojurescript/SRqs211zf6E/unsubscribe.
> > 
> > To unsubscribe from this group and all its topics, send an email to 
> > clojurescrip...@googlegroups.com.
> > 
> > To post to this group, send email to clojur...@googlegroups.com.
> > 
> > Visit this group at http://groups.google.com/group/clojurescript.

-- 
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 clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.

Reply via email to