I'm working through the video tutorials for Fulcro 3. It seems after part 7, the content becomes increasingly detailed. It appears to be like water from a water hose, as a beginner, or I just see the leaves, not trees, or the forest. I wonder if I really miss too much of the fundamental. Is there a better way to learn Fulcro 3?
I found that I watched the first 8 or so videos standalone, without breaking out any code. After that though I needed to play with the demo, and build some toy apps to help internalize the basic concepts. Everything made sense while watching those early videos but I found that once I tried to implement something from scratch, there was a lot of head scratching đ
What he said ^^^^. Learning on any kind of real level is not a passive activity. There are very few real fundamentals in Fulcro, then a lot of leaves built on top of those. Practice is the only real way.
Have you tried https://github.com/fulcro-community/guides/blob/main/minimalist-fulcro-tutorial/index.adoc? Did it work for you? Do you perhaps feel that you would need something practical to do while watching the videos? Perhaps playing with fulcro-template and trying to apply the ideas from the videos would help? I'd love to capture some tips for helping other learn Fulcro?
Thank you all for the tips. I was thinking that watching the tutorial would help me more effectively. @holyjak I did read your Minimalist Tutorial. When I studied that it appeared to be clear, but when watch the video after 7, it's seems a total different world.
So any idea what would have helped you? Perhaps a series of small, practical tasks to actually experience it for yourself?
Also, what do you mean by "after 7"? 8+9? Or those after, form state, state machines,...? I'd say those are advanced topics it is best to wait with until you get solid, practical experience with the basics and actually creating apps. You can make fine apps without those.
The https://book.fulcrologic.com/#_partial_routes section is quite illuminating as I tried to implement my first nested route. I'm still not sure how to handle an "index" route, i.e., "/accounts" that would render a list of accounts, but then also support routing to "/accounts/<id>" to display a single account. The two solutions in the book seem less than ideal. The "never issue partial" routes instruction becomes difficult once you're trying to route from the window url (you end up with hacks https://github.com/lgessler/glam/blob/master/src/main/glam/client/router.cljs#L71-L73 and L133-147) The solution to pre-issue relative routing instructions at application startup also seems kludgy. In both cases you've moved a bit of the routing logic somewhere else. Couldn't a router specify an initial target? Something like
(defrouter AccountsRouter
[this props]
{:route-segment ["accounts"]
:router-targets [AccountsIndexPage]
:initial-target AccountsIndexPage ; <--- routed to when a partial route is received
:always-render-body? false}
(common/loader))
..perhaps? Or am I missing something here (likely I suspect)?hi, author of the code snippet @ramblurr linked here. a little embarrassed that that mess of a router file gets cited from time to time đ
@tony.kay agree it's a worthy goal to not drag in the specific concerns of URLs into fulcro routers. I think the issue with the ["accounts"]
approach for the code for that project @ramblurr linked to is that it interfered with the structure I felt was most natural for Router
components: I wanted the components corresponding to ["accounts"]
and ["account" :id]
to be grouped under the same AccountRouter
component and not one there and one under RootRouter
.
Holding to that, the best I could come up with when I was hacking away was to do the null string hack. Maybe the more elegant solution is to just budge on that constraint though. Looking at it again, I can barely follow the router code I wrote just a few months ago
I feel like there'd be a lot of value in having a recipe book for common problems like this--I struggled a lot figuring out routing when I learned Fulcro, and I've seen others ask the same questions I had too. I know @souenzzo and @holyjak have done work on curating best practices. Are either of you aware of best practices for how to make fulcro ui routing work harmoniously with web routing?
I'd look more into this myself right now but my Fulcro writing's on pause through the end of the academic year (digression: I write Python these days and wow do I miss the maturity of Clojure-the-language and Clojure-the-ecosystem)
Indeed, I see the problem with the idea of an "initial-target", in fact this also affects the "pre-issue" solution.
If I enter the page at /accounts/edit
then click on "Accounts" in the navbar. If that navigates to ["accounts"]
the rendered comp will not change as ["accounts" "edit"]
is already active.
I see why the author of the linked project above used the ["accounts" ""]
convention to represent the /accounts
route.
Our URL path convention doesn't seem to map directly onto fulcro's composable dynamic routes
Right: The router is about UI routing, NOT URL ROUTING. For convenience a data structure (vector of strings) was chosen as it is simple to translate to-from a URL, but DR works on mobile, electron, etc.
Mapping to URLs is a simple function away, and such a function can trivially transform paths. But also, why not use ["accounts"]
and ["account" :id]
. Doing so eliminates the overlap problem and makes perfect sense.
Donât be so stuck on some way you saw it done in some REST app. Dropping an s
isnât a terrible leap or a cardinal sin đ
one could easily argue it is even the grammatical thing that should be done.
But my general point it: donât confuse convenience with design goals. The design goals of the composition in D.R. do not include âalways maps 1-to-1 with a browser URLâ. URL mapping convenience is a consideration, since often you can get the 1-to-1 mapping and that means you donât have to maintain an external data structure that maps from URLs to UI routes, but it is also a design goal that you are able to refactor your codeâŚMoving a route therefore technically changes the URL, which invalidates existing bookmarksâŚmeaning that you might want old URL to new URL aliasing. That part was a design goal (that you be able to deal with it when you want a browser URL to point to route that no longer matches the UI path).
This latter consideration also solves the problem of âwhat if my UI route doesnât match the URL I want?â