This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-01-29
Channels
- # announcements (17)
- # aws (12)
- # babashka (27)
- # beginners (85)
- # bristol-clojurians (1)
- # calva (16)
- # cider (3)
- # clara (7)
- # clojure (80)
- # clojure-europe (13)
- # clojure-italy (19)
- # clojure-nl (2)
- # clojure-norway (6)
- # clojure-poland (1)
- # clojure-spec (31)
- # clojure-uk (61)
- # clojurescript (29)
- # core-async (10)
- # cursive (7)
- # data-science (1)
- # datomic (29)
- # docker (3)
- # fulcro (120)
- # graphql (16)
- # hugsql (2)
- # leiningen (17)
- # luminus (2)
- # off-topic (36)
- # other-languages (3)
- # pathom (13)
- # re-frame (12)
- # ring (2)
- # rum (1)
- # shadow-cljs (126)
- # tools-deps (56)
- # vscode (5)
Hi all, is there an idiomatic way to change the route (to one that isn’t the default) while building the initial state for SSR?
I’ve tried modifying the ::dr/current-route of the relevant router, but that alone doesn’t seem enough. It appears I need to modify the queries as well, but when i use set-query*
I end up with transit errors about the anonymous functions in the metadata.
I would initialize the entire app and run it headless, and use the change-route function
I don’t remember putting functions in the metadata…oh…the components are metadata. I thought I changed that to their kw names in the component registry
So, if that is the case, it’s a bug…the fix is to change the dynamic query system to use the component’s key in the registry instead of the component itself…I thought that was aleady done
@U0BR5D7A6 Yeah, line 829 in components.cljc…it is still doing it the old way 😞
it isn’t that hard to fix…basically anywhere the component bit is used in the metadata needs to change to using the component registry key (which is a keyword)
An alternative is to do this: 1. Do NOT send initial state to the client. 2. Make an “initialize based on route” function 3. Render that on the server 4. Start the app and initialize normal state on the client, but DO NOT mount it yet. 5. Run (2) on the client 6. Mount the client with hydrate Then no initial state serialization is required.
@U0CL8APJ5 you were looking for a Fulcro task, I think…any interest in this? https://github.com/fulcrologic/fulcro/issues/367
great, hit me up if you need help understanding it…it really is just finding all the spots and changing the code to use keywords
and testing it all, of course…but any program that uses things like dynamic routers should fail pretty miserably if this is broken
Thanks guys! 😅
I’ve tried modifying the ::dr/current-route of the relevant router, but that alone doesn’t seem enough. It appears I need to modify the queries as well, but when i use set-query*
I end up with transit errors about the anonymous functions in the metadata.
my fulcro-inspect chrome extension just suddenly stopped loading with no significant change in my project that I can figure out. Any tips for how to troubleshoot why it’s not loading? I deleted .cp-cache
.shadow-cljs
folders and my JS build target folders and restarted the build.
my extension doesn’t have a “settings” button, but on the extensions list there is a “Details” button
there is a new version of inspect coming out, but we cancelled the release when I saw that problem
or, perhaps it is on the client side of Fulcro…in which case rolling back to 3.1.4 or earlier might fix it
@tony.kay I canceled the publishing after you reported the issue, its not moving forward
@thosmos I heard that happening to a lot of people before, usually re-installing the extension fixes it
If you can isolate it to either a reinstall or the Fulcro version (latest vs 3.1.4 or so) that would be really helpful as well
question about dynamic router and sync the URL, how you usually update the URL in response to a change-route
? there is a hook for it, or you change the URL first, detect that and then call change-route
?
@wilkerlucio I’m using pushy and have it detect the URL change and then call change-route from its handler (which I got from the F3 videos)
I understand they don't have a explicit connection, but as an app developer I'm trying to understand the best hooks/places to connect them
I have no opinion, because I have not really done it much 🙂…I’m not a fan of bookmarking stateful applications, but I do understand the need.
@thosmos thanks, I was aiming for that direction, just wanted to confirm if this is a sound approach that people tried before with this
@tony.kay in my case its important, sharing permalinks is a important feature of the app I'm working on
(defonce history
(pushy/pushy
(fn [p]
(let [r-segments (vec (rest (str/split p "/")))]
(timbre/spy :info r-segments)
(if (seq r-segments)
(dr/change-route SPA r-segments)
(dr/change-route SPA ["main"])))) identity))
(defn start! []
(pushy/start! history))
(defn route-to! [route-str]
(pushy/set-token! history route-str))
no idea about query params to represent stateful options though, as I haven’t crossed that bridge yet
perhaps that is what I was running into when I was testing the new version…I’m using the new version from a local build today and it is working so far
I have a form component that I’m using both for editing new and existing things. In the various field onChange handlers I have (fs/mark-complete! nil field-key)
so when loading the existing thing those get called and it appears dirty even though it’s not. Any advice for how to do that better? I’m thinking of having a :ui/loaded
flag in state that prevents the mark-complete! until after it’s loaded? reasonable approach or is there a better way?
The forms stuff is pretty free-standing, and uses the route will-enter and will-leave to do pretty much everything
so ["customer" "create" "ffffff-fff-ffff-ff"]
causes the state machine to use tempids on the form
I’m adding relational support today, and there is very limited form field type support so far
in my case I have a parent comp that is the route target and the child is the form comp with :form-fields
I assume it’ll be obvious how to pass through whatever is needed
I just added 4 entities in like 10 mins, and other than the ref stuff it all “just works”
but maybe if this just works I’ll collapse it into one component. One reason I have 2 layers is the parent loads lookup tables for dropdowns, etc
but RAD isn’t complete enough to use just yet…have not considered passing data from UI separate from what a route might use
I ran into some weird build errors when looking at RAD, and I have a rough draft milestone to deliver on Fri, so I skipped it for now. I think in the long run merging with RAD, at least in part, is gonna be the way to go. But for now I just need to get something working.
my problem was an order of operations error. I fixed it by adding the form-state in the post-load-mutation, whereas before I was adding the form-state to the small bit of props I had followed by a full load of the entity, so anything new triggered the dirty flag.
@thosmos I’ve had similar concerns and eventually came to a mental model which worked in all my cases so far, but is pretty opinionated: 1) no field => input is disabled 2) nil-valued field => input is enabled, but the value does not conform to spec, so user needs to enter smth 3) non-nil-valued field => input is enabled and its value validity is determined by spec; then you initialize all the missing values in pre-merge with nils or whatever suits for defaults, and you’re also adding form-state in pre-merge, so there might be nowhere to mark-complete before the load and furthermore you’re in control of everything that said, if your problem is pretty much solved by :ui/loaded and you need to 🚢 soon, i’d go with that. there’s a lot of caveats when implementing forms...
@tony.kay I understood you meant just to look at the source, but it usually helps me understand it more quickly when I can play with it in the demo
@UDQ2UEPMY thanks for the tips, adding to my notes for the future!
the book is in asciidoc. Download source and use asciidoctor to convert it to whatever you want (assuming there is a plugin)
@thosmos @tony.kay a simple implementation without adding external deps (using Google Closure Library):
(ns url-routing-with-closure
(:require [goog.events :as gevents]
[clojure.string :as str])
(:import [goog History]))
(defonce page-history
(doto (History.)
(.setEnabled true)))
(defn listen-nav-change [f]
(gevents/listen page-history "navigate" #(f % (.-token %))))
(defn change-route [path]
(.setToken page-history (str/join "/" path)))
(defn change-route-from-nav-event [app]
(fn [_ token]
(dr/change-route app (str/split token "/"))))
I would just add in one more layer: a function that translates the URL to the vector instead of split
I'm using this in combination with path-to
(change-route (dr/path-to SearchPage))
yeah, I agree we inprove on the aliasing, that's was just initial URL connection setup, we can go crazy from that 🙂
you want to make a PR, @wilkerlucio? Some new ns, since we cannot pollute dr with goog.events and History
I would like to spend more time experimenting with it before adding to the library, find a good API first
@wilkerlucio that’s dope, real handy when you need full control, esp so when making Web+React Native in one app (because you can’t just require say accountant
in RN, it would crash the app, so you fork it anyway)
jfyi smth like accountant
also allow for <a href> links to both be routable without page reload and to be a real links in the sense that you can Cmd+Click to open it in a new tab, which might be critical for many apps (as it was for us), but of course that’s just one more fn
hello everyone, as you may know already, the new Fulcro Inspect on electron has a nice new DB Explorer
tab, currently its not available on the chrome that's published, the reason is that Google is now making much harder to upload extensions, in the past I could upload and have it updated on the store in about 30 min, now it may take weeks (requires manual checking, because the extensions needs some extensive permissions to work on any page). Given that, the deploys now need to be more careful (if we get a bad version out, it may take a while to get it fixed), also because of that I like to encourage you to build and install the extension yourself, this way we can have more people trying it before the store release, if you wanna do so you can find instructions at https://github.com/fulcrologic/fulcro-inspect#building-chrome-extension. If you do that now you can use the DB Explorer
right now! 🙂 Cheers!
having an issue getting a component to refresh after a load!
the component itself queries for a link, and I’m adding a refresh
option to the load to update that link. for some reason, although my app db is updated the component doesn’t seem to be re-rendering. any high level ideas about how I might be approaching this incorrectly?
is your refresh referring to the link or to a key in the parent that contains the link?
assuming if the link in the query looks like [:my/thing '_]
the options map in my load!
would look like {:refresh [:my/thing]}
yep, has an ident and that does work. unfortunately quite a few components are changed by the data I’m loading, making sure each has an ident and listing it in the refresh is a little unwieldy
Try switching to keyframe renderer, to see if that solves your refresh issues. Then you can optimize it with keyframe2 renderer. http://book.fulcrologic.com/#RenderingOptimizations
my component has an initial state map declared per http://book.fulcrologic.com/#_a_warning_about_ident_and_link_queries