This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-08-02
Channels
- # announcements (3)
- # aws (2)
- # babashka (60)
- # beginners (21)
- # cljs-dev (35)
- # cljsrn (3)
- # clojure (53)
- # clojure-android (2)
- # clojure-australia (3)
- # clojure-europe (45)
- # clojure-france (4)
- # clojure-nl (4)
- # clojure-uk (6)
- # clojurescript (33)
- # core-typed (1)
- # cursive (13)
- # datomic (6)
- # duct (1)
- # emacs (2)
- # fulcro (10)
- # introduce-yourself (3)
- # jobs (2)
- # jobs-discuss (13)
- # leiningen (1)
- # malli (19)
- # missionary (63)
- # music (1)
- # off-topic (21)
- # pathom (3)
- # polylith (18)
- # practicalli (12)
- # proletarian (1)
- # reagent (40)
- # reitit (23)
- # releases (1)
- # remote-jobs (1)
- # ring (14)
- # ring-swagger (1)
- # shadow-cljs (13)
- # sql (30)
- # testing (27)
- # tools-deps (31)
- # vim (10)
- # xtdb (4)
how would I refactor this query into a child component? I'm confused why comp/get-query
wraps the ImageList query in a list instead of splicing it directly into the Gallery query.
;; this works
(defsc Gallery [this {:gallery/keys [uuid title images] :as props}]
{:query (fn [] [:gallery/uuid
:gallery/title
{'(:gallery/images {:limit 5}) (comp/get-query Image)}])
:ident :gallery/uuid}
(div :.ui
(h3 title)
(div (map ui-image images))))
;; this doesn't: ImageList query is wrapped in ()
(defsc ImageList [this {:gallery/keys [images]}]
{:query (fn [] {'(:gallery/images {:limit 5}) (comp/get-query Image)})
:ident :gallery/uuid}
(div (map ui-image images)))
(def ui-image-list (comp/factory ImageList))
(defsc Gallery [this {:gallery/keys [uuid title images] :as props}]
{:query [:gallery/uuid
:gallery/title
(comp/get-query ImageList)]
:ident :gallery/uuid}
(div :.ui
(h3 title)
(ui-image-list props)
(div (map ui-image images))))
1. In ImageList
query, you need to wrap the query in a vector, [{..}]
- without the brackets, you're accidentally creating a union query
2. Seems to me, you also need to fix the Gallery
query to make an explicit join, something like:
[:gallery/uuid
:gallery/title
{:images (comp/get-query ImageList)}]
3. But (2) may actually not be what you want, because you are now conflating the Data hierarchy with the UI hierarchy. Here are some good suggestions on how to reconcile these 2 worlds: https://blog.jakubholy.net/2020/fulcro-divergent-ui-data/;; Probem 1: as @pithyless metioned, need a vector around the query...the list is fine for params
(defsc ImageList [this {:gallery/keys [images]}]
{:query (fn [] [{'(:gallery/images {:limit 5}) (comp/get-query Image)}])
:ident :gallery/uuid}
(div (map ui-image images)))
(def ui-image-list (comp/factory ImageList))
;; Problem 2. Children are ALWAYS composed with a join. you MAKE UP a key for it:
(defsc Gallery [this {:gallery/keys [uuid title image-list] :as props}]
{:query [:gallery/uuid
:gallery/title
{:gallery/image-list (comp/get-query ImageList)}]
:ident :gallery/uuid}
(div :.ui
(h3 title)
(ui-image-list image-list)
or this one: https://youtu.be/HCVzG2BLRwk
Somewhere I've probably written about what not to do with queries...I know I've mentioned that "stealing" the child query for the parent isn't legal, but in this case you just composed it in strangely. Remember that get-query
is going to return a vector (except for unions, which you are not using). So, but putting [... (get-query X)]
you've make a [... [:x-prop]]
query, which is clearly not legal EQL. Subqueries are always joins.
thanks for the clarification. the reason I wanted to compose it this way is to be able to refresh the sorting/filtering of the images without refreshing the rest of the gallery attributes. I'm a still wrapping my head around the example though, if you pass image-list
into ImageList
, how can it get the :gallery/uuid
? and with this line:
{:gallery/image-list (comp/get-query ImageList)}
wouldn't that nest an extra unwanted layer into the EQL query, like:
{:gallery/image-list [{:gallery/image-list ...}]}
finally, since the key is made up- which part corresponds to the pathom resolver on my server? the actual key for the images (and the datomic attribute) is :gallery/art
. so that would be in the ImageList
query right?
{:query (fn [] [{'(:gallery/art {:limit 5}) (comp/get-query Image)}])
:ident :gallery/uuid}
What do you mean by refreshing sorting / filtering of images without refreshing the rest? You could (m/set-field! this :ui/sorting...) inside Gallery (assuming getting rid of the ImageList defsc and only have Gallery And Image), That only changes sorting and rerenders Gallery (where you could do (->> images (sort-by sorting) (map UI-image)). If that isn't what you want - what do you want?
the gallery set might be too large to be loaded in the client (10k images - though I haven't tested it) so I'm doing filter, sorting, and limiting on the backend in the resolver. I'd like to be able to update the ImageList
query and do a load!
to refresh the list
Ah, ok. That is not really different from the pagination example here https://book.fulcrologic.com/#_paginating_large_lists, is it? With Gallery = LargeList (and e.g. :gallery/current-image-list
= :list/current-page
), ImageList = ListPage (and :image-list/images
= :page/items
), Image = ListItem.