This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-04-25
Channels
- # admin-announcements (5)
- # arachne (1)
- # beginners (29)
- # boot (36)
- # cider (110)
- # clara (1)
- # cljs-dev (3)
- # cljs-edn (14)
- # cljsrn (24)
- # clojure (63)
- # clojure-belgium (3)
- # clojure-dusseldorf (5)
- # clojure-greece (9)
- # clojure-russia (142)
- # clojure-sg (15)
- # clojure-uk (20)
- # clojurebridge (4)
- # clojurescript (58)
- # data-science (1)
- # datomic (37)
- # editors (2)
- # editors-rus (7)
- # emacs (1)
- # garden (31)
- # hoplon (3)
- # jobs-discuss (8)
- # keechma (86)
- # leiningen (1)
- # liberator (2)
- # mount (23)
- # off-topic (2)
- # om (18)
- # onyx (42)
- # planck (1)
- # quil (6)
- # re-frame (8)
- # reagent (3)
- # ring-swagger (1)
- # specter (4)
- # untangled (1)
@roberto: you can add meta data on collections and named items
another question, in the Place My Order example, specifically this https://github.com/keechma/keechma-place-my-order/blob/66cd3138897f72f9e683dae2e562610c55cd8984/client/src/client/controllers/restaurant.cljs#L24
the :recordings :current
entity is being attached some meta data. I noticed this overwrites the meta data for :recordings :list
.
that shouldn’t be happening. I’ll investigate and get back to you
but ti should return the whole new version of atom with only the (relevant) part of the data changed.
hmmm, for me it is changing the entire atom, deleting the :list
and only :current
is present
it deletes only the meta data or the data too?
also how are you retrieving the meta data in your ui component?
yeah, that’s the right way
but only for troubleshooting, was wondering why my list disappeared when I selected an item
that definitely shouldn’t be happening
you are seeing this behavior only in your app or in place-my-order app too?
i haven’t tried place-my-order
, planning on doing that today. Seeing it on my app right now, which is tightly based on place-my-order
can you paste the code that shows that behavior?
this is the function in the controller for displaying the individual item:
(defn update! [app-db-atom updater]
(reset! app-db-atom (updater @app-db-atom)))
(defn load-recording
[app-db-atom slug]
(update! app-db-atom
#(edb/insert-named-item % :recordings :current {} {:is-loading? true}))
(let [recording (edb/get-item-by-id @app-db-atom :recordings (js/parseInt slug))]
(when-not recording
(go
(let [req (<! (http/get (str "/api/recordings/" slug)))
meta {:is-loading? false}
[success data] (unpack-req req)]
(update! app-db-atom
#(edb/insert-named-item % :recordings :current data meta)))))))
this is the what loads the list:
(defn load-collection
[entity list app-db-atom req]
(do
(reset! app-db-atom
(edb/insert-collection @app-db-atom entity list [] {:is-loading? true})))
(go
(let [[is-success? body] (unpack-req (<! req))
data (if is-success? (:recordings body) [])
max-pages (.ceil js/Math (/ (:total body) page-size))
meta (if is-success?
{:is-loading? false
:current-page (:current-page body)
:total (:total body)
:max-pages max-pages
:next-page (next-page (:total body) max-pages (:current-page body))}
{})]
(reset! app-db-atom
(edb/insert-collection @app-db-atom entity list data meta)))))
(def load-recordings (partial load-collection :recordings :list))
this is the list controller:
(defrecord Controller []
controller/IController
(params [_ route]
;;Only run this controller when the route is home or "recordings".
(let [route-data (:data route)]
(when (or (and (= (:section route-data) "recordings")
(:page route-data))
(= (:section route-data) "home"))
route-data)))
(start [this params app-db]
(if (= "home" (:section params))
(controller/redirect this {:section "recordings" :page 1})
(when (:page params)
(controller/execute this :load-recordings params)))
app-db)
(handler [_ app-db-atom in-chan out-chan]
(go (loop []
(let [[command args] (<! in-chan)]
(case command
:load-recordings (let [url (str "/api/recordings?page=" (:page args))
req (http/get url)]
(load-recordings app-db-atom req))
(get-collection app-db-atom))
(when command (recur))))))
(stop [_ _ app-db]
(edb/remove-collection app-db :recordings :list)))
(defn get-collection
[app-db-atom]
(prn "METAS: " (edb/get-collection-meta @app-db-atom :recordings :list))
(prn "COLLECTION: " (edb/get-collection @app-db-atom :recordings))
(edb/get-collection @app-db-atom :recordings :list))
this line won’t return anything (prn "COLLECTION: " (edb/get-collection @app-db-atom :recordings))
because you need to give the name of the collection
if :recordings
is the entity name
you need to pass the :list
as the collection name too
this is the controller for the selected item:
(defrecord Controller []
controller/IController
(params [this route]
(let [route-data (:data route)
page (:section route-data)
slug (:slug route-data)]
(when (and (= page "recordings")
(not (nil? slug)))
route)))
(start [this params app-db]
(let [slug (get-in params [:data :slug])]
(controller/execute this :current-recording slug))
app-db)
(handler [this app-db-atom in-chan out-chan]
(go (loop []
(let [[command args] (<! in-chan)]
(case command
:current-recording (load-recording app-db-atom args)
:backup-to-vimeo (backup-to-vimeo app-db-atom args)
nil)
(when command (recur)))))))
yeah, but it should update just the part of the internal map. I’ll definitely have to check what’s going on
btw you can shorten the code inside the handler
functions by using the dispatcher
function https://github.com/keechma/keechma-todomvc/blob/master/src/keechma_todomvc/controllers/todos.cljs#L28
I’m not using EDB in that app
that’s why
EDB has it’s own internal structure which is why I’m replacing the whole atom
I’m probably understanding something wrong, isn’t app-db-atom completely replaced with a new value by reset!
? Or is this not a typical clojure atom?
it is, but the map inside should retain the old data.
it seems that edb is removing some data it shouldn’t
@roberto I think this part is the problematic
it seems that you’re calling get-collection
before load-recordings
is finished
so, when an item is selected load-recordings
shouldn’t be called, because it is already there
but you load only one item when the item is selected, right?
so basically what needs to happen is: both controllers need to load their data, list and current
and they will be merged inside the EDB
so you will always have only one version of the current recording
but, you still need to load the collection :list and named item :current
which is different from the place-my-order app
because it doesn’t have the master-detail view
it’s either the list of restaurants or one restaurant
do you see both requests (list and current) in the console when you have the detail page open?
so the flow is the following: initial view displays the master list, that does an xhr request
then when we select an item from that list, we don’t do any xhr requests because the items are already downloaded
oh, there’s another problem I just noticed
you’re returning the whole route-data
from the params function
which causes the controller to be restarted
controller manager checks what is returned from the params function
only the subset of data your controller cares about
this seems to be a documentation issue.
basically, controller checks what is returned from the params function
and based on that decides what to do with the controller
Whenever the URL changes, the manager controller will do the following: It will call params function of all registered controllers It will compare returned value to the last returned value (returned on the previous URL change) Based on the returned value it will do the following: If previous value was nil and current value is nil it will do nothing If previous value was nil and current value is not nil it will start the controller If previous value was not nil and current value is nil it will stop the controller If previous value was not nil and current value is not nil but those values are same it will do nothing If previous value was not nil and current value is not nil but those values are different it will restart the controller