0

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.

ftravers
  • 3,809
  • 3
  • 37
  • 38

1 Answers1

0

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.

Chris Murphy
  • 6,411
  • 1
  • 24
  • 42
  • Hi Chris thanks for answering...you are (were) right in your answer, but because I didn't ask correctly, I didn't get the answer I was looking for. I've added to the question to clarify what exactly I'm looking for. Thanks again! :) – ftravers Dec 23 '16 at 09:19
  • No problem ftravers. I agree that reader functions should be superfluous if your data is normalised and so db->tree will always be used. No point in them all looking the same. To get rid of them entirely (certainly on the client - I don't have much experience on the server) just switch your project to Untangled. – Chris Murphy Dec 23 '16 at 10:17
  • From https://github.com/omcljs/om/wiki/Documentation-(om.next)#reconciler: "If not an atom the reconciler will normalize the data with the query supplied by the root component". You are passing in an atom , so your data ought to be already normalized, yet is not. `db->tree` assumes normalized data. To check that your data is normalized see: https://github.com/chrismurrph/default-db-format – Chris Murphy Dec 24 '16 at 01:06
  • Hi Chris, thanks again for taking the time. My understanding of 'Normalized' is that data that is duplicated in the UI is not duplicated in the DB, but _referenced_ via an `ident`. In my case I'd say my data *is* normalized because there is only one value. Needless to say `(om/db->tree [:user] @app-state @app-state)` returns: `{:user {:name "Fenton"}}`, so I think db->tree works fine. I'm just trying to get a thorough understanding of how om.next works before I layer something more on top with Untangled...I dont like being too confused about what my layers are doing. Thanks again! :) – ftravers Dec 24 '16 at 01:32