4

I'm trying to understand when we must deref a cursor to get its value.

In the om cursors wiki it states that event handlers are considered not part of the render phase, and therefore cursors in handlers should be drefed. Same is shown in the Basic-tutorial:

(defn contact-view [contact owner]
  (reify
    om/IRenderState
    (render-state [this {:keys [delete]}]
      (dom/li nil
        (dom/span nil (display-name contact))
        (dom/button #js {:onClick (fn [e] (put! delete @contact))} "Delete")))))

But, in the TodoMVC code, the handlers (onclick, onchange...) use the cursor without derefing it:

(dom/button
   #js {:className "destroy"
        :onClick (fn [_] (put! comm [:destroy todo]))}))

So, what is the correct way?

Thank you.

Raphael Boukara
  • 396
  • 3
  • 11
Asher
  • 1,019
  • 9
  • 22

1 Answers1

0

Notice that delete and comm are not cursors but core.async channels. The put! operation adds a message to the channel which is handled here.

Cursors are a way of wrapping state (called app-state in om). There are two things you might want to do with that state:

  1. Change the state: when you want to change your app-state, you call om/transact! or om/update! on one the cursors to the app-state (deref never needed). Om schedules this transaction to be shown in the next render phase.
  2. Read the state: when reading during the render phase (inside the render and render-state functions, the cursor works like its value, i.e., you don't need to deref it. At any other point in time, the cursor might be being transacted on or have a schedule transaction, so you want to deref it to get the current value and not some inconsistent state.
sbensu
  • 1,416
  • 8
  • 8