Why doesn't my query get passed into my reader?

70 views Asked by At

Questions

My webpage only has the output: {:user {}} with the following code.

(ns omn1.core
  (:require
   [om.next :as om :refer-macros [defui]]
   [om.dom :as dom :refer [div]]
   [goog.dom :as gdom]))

(defui MyComponent
  static om/IQuery
  (query [this] [:user])
  Object
  (render
   [this]
   (let [data (om/props this)]
     (div nil (str data)))))

(def app-state (atom {:user {:name "Fenton"}}))

(defn reader [{q :query st :state} _ _]
  (.log js/console (str "q: " q))
  {:value (om/db->tree q @app-state @app-state)})

(def parser (om/parser {:read reader}))

(def reconciler
  (om/reconciler
   {:state app-state
    :parser parser}))

(om/add-root! reconciler MyComponent (gdom/getElement "app"))

When I check the browser console, I notice that my query is nil. Why doesn't it get passed into my reader function?

This comes from a motivation to keep my code to a minimal # of LOC as possible, and also DRY. So I'd like to have one read function that will work with a properly set up database, and normal nominal queries. If you pass regular queries to om/db->tree indeed db->tree does this. db->tree will take any proper query and return you a filled out tree of data. Maybe another way to phrase the question is can someone demonstrate a reader function that does this? I.e. leveraging db->tree to resolve the value of a query. I don't want to write a custom reader for each query I have. If all my queries obey the regular query syntax AND my DB is properly formatted, I should be able to use one reader function, no?

The example provided in the om.next quick start - thinking with links doesn't work:

(defmethod read :items
  [{:keys [query state]} k _]
  (let [st @state]
    {:value (om/db->tree query (get st k) st)}))

as stated before query is nil sometimes, and the 2nd and 3rd arguments are different from what is proposed as how to use this function from the tests which all use: st for both 2nd and 3rd arguments. Confused.

1

There are 1 answers

4
Chris Murphy On

From the Om.Next Quick Start tutorial (https://github.com/omcljs/om/wiki/Quick-Start-(om.next)), read has this signature:

[{:keys [state] :as env} key params]

So there is no access to a query data structure.

Usually the setup is to have a multimethod for each query, and use the query's params to return some part of the state:

(defmulti read (fn [env key params] key))

(defmethod read :animals/list
  [{:keys [state] :as env} key {:keys [start end]}]
  {:value (subvec (:animals/list @state) start end)})

Here :animals/list is the key of the query. So this is how you can access the key and params of the query.