This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-09-28
Channels
- # announcements (2)
- # beginners (19)
- # calva (8)
- # cider (5)
- # cljsrn (13)
- # clojure (35)
- # clojure-conj (3)
- # clojure-spain (1)
- # clojure-uk (2)
- # clojurescript (4)
- # clojutre (4)
- # cursive (13)
- # data-science (2)
- # datascript (1)
- # datomic (5)
- # duct (4)
- # fulcro (76)
- # funcool (5)
- # jobs (5)
- # off-topic (10)
- # remote-jobs (7)
- # rewrite-clj (8)
- # spacemacs (3)
- # sql (2)
- # xtdb (25)
More videos coming to the YouTube playlist. One on dynamic UI driven by data, and two on UI state machines. The first UI state machine one is a bit longer than usual, but I didn’t see a great way to break it up. The second one is just the final few minutes of what I probably should have just done in the first one…but I’m not up for video editing, so I’ll just post it as 2.
@tony.kay In section 3.4.2 of the Fulcro 3 book, http://book.fulcrologic.com/fulcro3/#_shadow_cljs_compiler_configuration, the code listing has port 8000 and the text has 8080 for dev-http. I doubt anyone would be confused by the typo, but I figure I'd point it out. I wasn't sure it was worth a PR, but if you want one I can.
having trouble triggering a refresh
after a load. a component is querying for a link at the root of my app db which is a list of idents pointing to a different table in my db.
e.g. my component queries for user/active-things
which is composed of [thing/id thing-id]
idents pointing to the thing/id
table.
I’m dispatching loads to update the relevant [thing/id thing-id]
idents, but they aren’t triggering a ui refresh in my component despite the app state being updated
my load!
call looks like:
(df/load! mounted-app [:thing/id thing-id] Thing {:refresh [:user/active-things]})
any pointers for how to debug?unless the list itself changes, that won’t refresh the components using active-things
huh that’s interesting. would have figured that an ident in that list getting updated would cause a re-render for a component querying for :user/active-things
so, you have [:user/active-things '_]
in some component query, and it then renders everything from that table?
technically getting fed into and rendered in a child but the parent’s data isn’t updating either
yeah if I trigger any other ui update that causes a re-render (e.g. toggle some field on the component)
yep I’m just updating a thing/field
via that load!
and the component is not getting updated
don’t know why this would affect things, but the load!
is getting dispatched inside of a setInterval fn set up in my app’s client-did-mount
cb
let me see the code for the Thing and the component rendering them…not so much all the DOM, just the query/ident/options stuff
so the example I mentioned above was obviously a little contrived. here’s the gist of what I’m doing: TestRun
and TestRunTest
are query components I use to create my initial query and do post-render load!
s. Project
is actually doing the rendering here, and doesn’t get refreshed post-`load!`
(defsc TestRunTest [this props]
{:query [:test/id]
:ident (fn [] [:tests/by-id (:test/id props)])})
(defsc TestRun [this props]
{:query [:test-run/id
:test-run/progress
{:test-run/test (comp/get-query TestRunTest)}]
:ident :test-run/id})
(defsc Project [this props]
{:ident (fn [] [:pages/by-id :project])
:route-segment ["project"]
:will-enter (fn [_ _] (dr/route-immediate [:pages/by-id :project]))
:will-leave (fn [_ _] true)
:initial-state (fn [params]
{:ui/project-page.tests-filter-bar-sort-selection "Test name A-Z"})
:query [:ui/project-page.tests-filter-bar-sort-selection
{[:current-user/active-test-runs '_] [{:test-run/test [:test/id]}
:test-run/progress]}]}
; if I log (:current-user/active-test-runs props) here, the data is not refreshed post load
(map test-run-cards (:current-user/active-test-runs props)))
:client-did-mount (fn [mounted-app]
(dr/initialize! mounted-app)
(js/setInterval (fn []
(let [app-state @(::fulcro-app/state-atom mounted-app)
active-test-runs (compute-active-test-runs app-state)]
(doseq [test-run active-test-runs]
(let [test-run-id (:test-run/id test-run)]
(df/load! mounted-app [:test-run/id test-run-id] TestRun {:refresh [:current-user/active-test-runs]})))))))
ok, so first off, your refresh should not be needed since you’re not actually changing that list…Project is never going to update from that load, because that list didn’t change. That is correct behavior.
however, any on-screen TestRun component should auto-refresh when any props change in the db
I don’t see you using a proper factory for rendering TestRun…what is test-run-cards
?
so the components using that TestRun
data passed down from the Project
don’t actually have an ident/query that’s composed into root – it’s passed in from the parent
I went down that route because each of the cards that was getting rendered had ui data that needed coordinating by the parent. someone had advised me that the easier way to do that would be to have the parent component (i.e. the Project
component) manage the state and pass everything down to simple factory components
coordination from the parent should happen through computed props, generally (if it is computed data)
I would generally also not use a link query for that list, since I would think the Project component itself probably needs a private to-many edge
(load! app :project/active-test-runs TestRun {:target [...project ident... :project/test-runs]})
that all makes sense.
I guess what wasn’t clicking for me before and the reason I went down this frankenpath: each child of Project is basically a component that takes a test-run-id and renders some dom with some computed state passed in. I couldn’t really wrap my head around how to compose the query/ident for that child card component, as well as how to compose that into the parent Project
I don’t know if any of what I just wrote makes sense. feel like my mental model of how rendering works is a little borked. really appreciate you coming down this rabbit hole and helping me out. am diving into that video now