This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-02-06
Channels
- # adventofcode (1)
- # aleph (9)
- # announcements (22)
- # beginners (59)
- # boot (8)
- # calva (1)
- # cljdoc (7)
- # cljs-dev (10)
- # cljsrn (9)
- # clojars (10)
- # clojure (23)
- # clojure-dev (6)
- # clojure-europe (3)
- # clojure-italy (26)
- # clojure-nl (3)
- # clojure-seattle (1)
- # clojure-spec (46)
- # clojure-uk (85)
- # clojurescript (97)
- # core-async (13)
- # cursive (3)
- # data-science (10)
- # datomic (156)
- # duct (34)
- # emacs (37)
- # figwheel (3)
- # figwheel-main (9)
- # fulcro (59)
- # hyperfiddle (4)
- # immutant (1)
- # jackdaw (3)
- # jobs (1)
- # off-topic (112)
- # parinfer (1)
- # qlkit (2)
- # re-frame (1)
- # reagent (35)
- # ring-swagger (2)
- # shadow-cljs (104)
- # spacemacs (9)
- # speculative (12)
- # tools-deps (30)
- # yada (10)
ok, so the module is compiling and loading, but now it seems that the set-query!
is not working, or rather that the routing target component is not getting the query update by the time it renders, since it still has the initial temporary [{:loaded component [*]}]
query when the attempt is made to load its new query's component to render it: (some-> this prim/get-query prim/query->ast1 ,,,)
call. However the new query IS visible in the router's list of queries and components inside of Fulcro Inspect.
Hey @thosmos. I have not personally tried it with code splitting…so you’re the guinea pig. Are you saying you’re nesting a router in the dynamic loaded part? Or just a target?
At the moment I just have one router, the root router, and it and all of its route targets are in the main module. Each route target has a simple query of [{:module-comp [*]}]
When a route attempt is made to, in this case the "about" module, the route target's :will-enter calls dr/route-deferred. In the code module there's a definition for a regular defsc
module
(defsc AboutComp [this {:keys [about/hello]}]
{:query [:about/hello]}
and the module loading code calls set-query like so:
(prim/set-query! reconciler class {:query [{:about-comp (prim/get-query AboutComp)}]})
But that query is not finding its way in AboutPage's (the route target) query by the time its render is called, which is where the attempt is made to load the AboutComp's factory and state.The loaded module should be written to call a function that sets the target ready…e.g. at the bottom of the ns where you would tell the loader that you’ve loaded. That way the main program doesn’t have to know anything about the code in the module.
(tell the loader you loaded)…either way, referring to the AboutPage in your main app will prevent code splitting
now, if the load immediately calls the then
(which it could if nothing was actually split), then it might run on the same execution that the will-enter is running on, which would be a nested transact!
, which is not assured to work. You could try using ptransact! instead (which is safe to call from within transact context). Either way you’re going to need to fix it so your parent code doesn’t mention anything in the module you wish to split.
hmm, not sure I understand, I have two components, AboutPage (the route target) and AboutComp (which is defined in the module)
Yes I do get-query AboutComp in the module code and then use the value of :class that was set by the main module to set query on AboutPage to use AboutComp's query?
yes that is what I'm doing (or rather my first attempt was), but I didn't use the state map in the get-query so I'll try that first before working up an example
my second attempt was to pass a reference to the loaded class back to the first component and try to set-query from there.
I tried adding the state-map to the get-query, but that didn't resolve the issue. I put the relevant pieces in a gist here: https://gist.github.com/thosmos/3184979b6b3774ac9fef40e752bae92d
Those swaps should just be in a mutation: https://gist.github.com/thosmos/3184979b6b3774ac9fef40e752bae92d#file-2_about-cljs-L24
https://gist.github.com/thosmos/3184979b6b3774ac9fef40e752bae92d#file-2_about-cljs-L33 You might need a follow-on read here to tell Fulcro what should refresh
This get-query won’t work right without a state map: https://gist.github.com/thosmos/3184979b6b3774ac9fef40e752bae92d#file-1_routing-cljs-L30
(some-> this (prim/get-query (prim/component->state-map this)) prim/query->ast1 :component prim/factory)
I don’t think Fulcro sets the dyn var during render, it’s more during it’s use of get-query…I could be wrong here, but it is suspect
progress! I'm now seeing the module component when I initially load the page on another route and switch to it, but if the initial load is on /about, then it's only loading it for a moment, long enough to see it, then it disappears and shows the pending and error routes.
I updated the gist with the latest https://gist.github.com/thosmos/3184979b6b3774ac9fef40e752bae92d
(get-query this state-map)
…dynamic queries are resolved via the state map. There is a dynamic var that supplies that during render, but outside of the render loop it has to be manually supplied (or the dynamic var set).
Is there an idiomatic way to use react’s renderToStaticMarkup
?
Or rather, on the server, some call analogous to renderToStaticMarkup
@U0BR5D7A6 http://book.fulcrologic.com/#_rendering_with_initial_state https://github.com/fulcrologic/fulcro/blob/8792813a1304f73a912e21a0945402055a8f9795/src/main/fulcro/client/dom_server.clj#L397 render-to-str
seems to be the only one in fulcro
If you run server-side in node, then all js libs are available…In Fulcro, we have to have clj code that can “interpret” the UI…so, render-to-str is actually a CLJ implementation of React’s server render stuff.
that’s a great idea! running it on node would be perfect for my use case
It looks like fulcro/pathom makes heavy use of namespaced keywords in queries (“input” “output”). It makes sense to me now, but I am curious: this looks like it would fit well with datomic (which I don’t use). Do people do things differently with ex. SQL / other databases? Do they add an extra step in the resolver (like prefixing elements with the table name)?
@nha in my current project I am using PostgreSQL as a database, and yes my resolvers do have a step to prefix elements. Perhaps I could abstract it away but for now I have kept it very explicit, e.g.:
(defresolver course-resolver
[env input]
{::pc/input #{:course/id}
::pc/output [:course/name]}
(let [course (Course (:course/id input))]
{:course/name (:name course)}))
No problem 🙂 Also, I have found it useful to only provide IDs for references. For example:
(defresolver course-resolver
[env input]
{::pc/input #{:course/id}
::pc/output [:course/name {:course/task-sets [:task-set/id]}]}
(let [course (Course (:course/id input))
task-sets (map (fn [{:keys [id]}] {:task-set/id id})
(db/select TaskSet :course_id (:id course)))]
{:course/name (:name course)
:course/task-sets task-sets}))
performance-wise it’s not ideal as it suffers from the N+1 queries problem, but conceptually it’s nice imho
You could also look into something like https://walkable.gitlab.io/ (I haven’t used it yet)