This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-04-01
Channels
- # announcements (3)
- # beginners (59)
- # calva (23)
- # cider (58)
- # clojure (125)
- # clojure-dev (18)
- # clojure-dusseldorf (1)
- # clojure-europe (21)
- # clojure-germany (1)
- # clojure-hamburg (1)
- # clojure-italy (13)
- # clojure-nl (29)
- # clojure-poland (3)
- # clojure-spec (61)
- # clojure-uk (74)
- # clojurescript (12)
- # core-async (6)
- # cursive (4)
- # data-science (7)
- # datomic (14)
- # defnpodcast (1)
- # events (4)
- # fulcro (72)
- # juxt (36)
- # kaocha (3)
- # nginx (3)
- # off-topic (14)
- # pathom (5)
- # ring-swagger (68)
- # shadow-cljs (25)
- # spacemacs (8)
- # sql (42)
- # tools-deps (8)
- # vim (6)
I am fighting with Intellij and fulcro.incubator.dynamic-routing
and then the defsc-route-target
for some reason intellij does not want to resolve it. Anyone here ran into the same issue?
I haven't used Intellij in a long time, but this may be helpful if you aren't familiar already: https://cursive-ide.com/userguide/macros.html (and if you are already familiar -- https://github.com/cursive-ide/cursive/issues/1505#issuecomment-319307955)
Thank you I am familiar, and these are not the issues unfortunately 😞
@mitchelkuijpers you have to go into incubator and resolve defsc-extended
Fixed it by first adding a resolve-as
for defextened-defsc
and the resolving
had just figured it out
I resolved it as def
Thank you
let me know how the dynamic router goes for you…we’re loving it on the projects I’m using it on
would be very cool if libs could hint cursive about resolving stuff
We are already using it, but this is the first I am gonna try it out
yeah, maybe it could read from metadata
Or a simple xml file in the jar or something
More because cursive is already using it 😛
But yeah metadata would be cool
Fulcro 2.8.8 adds a (long overdue) global component registry: http://book.fulcrologic.com/#_the_component_registry_version_2_8_8
> tracking classes (by name) in app state (which cannot appear there as “code”). do you have an example use-case for this @tony.kay?
I’m adding one to incubator now: UI state machines need to track the component class of an actor. I was doing that via metadata on the idents; however, Inspect doesn’t get this metadata, so if you restore a snapshot of app state the state machine stops working. With a registry, I can simply store the FQ names of the classes in app state. Things end up more visible to the user, and inspect works properly. Another use-case would be a mutation that needs to refer to a component for a data merge, where you’d also like to require that mutation ns with the UI code (for aliasing convenience). Doing so in both directions would create a circular ref. You can fix this latter one by simply typing out the long name, but this gives you the option of typing the long name in the mutation instead of in every mutation call site.
that's a good point to send/store the metadata as well, we can make this available on inspect
we need to be careful @U066U8JQJ …the metadata is mainly used to store non-serializable stuff
yeah, true, is there something other than the components that is not serializable and goes there?
also, dynamic queries go in app state, and they need metadata to point to the classes…I still need to patch that to use the new registry instead
yeah, I'm thinking it can be useful even if it's not complete
and maybe we can have a custom encoder for components, that could send relevant information about it (just the name would be useful already)
makes sense, I was thinking about the usefulness of having the meta data in inspect as well, but agreed its not enough to fix the snapshot
Code splitting is another one: When you load code, you need to be able to look up the loaded component
you cannot refer to it in the base program directly, so you need someplace that it can “register itself”…I was leaving this to ad-hoc implementation, but now the registry can serve as that location
I am fighting with dynamic routing for some reason my deferred never seems to resolve
:will-enter (fn [reconciler {:keys [issue-id] :as props}]
(when-let [issue-id (some-> issue-id (js/parseInt))]
(let [ident [:my/ident issue-id]]
(dr/route-deferred ident
#(do
(js/console.log (str "loading " ident))
(prim/transact! reconciler `[(kit-utils/load-templates)])
(df/load
reconciler
ident
Issue
{:marker false
:abort-id :issue-load
:initialize true
:post-mutation `dr/target-ready
:post-mutation-params {:target ident}}))))))
@mitchelkuijpers does your ident for the route target match? other than that, I don't see anything that jumps out as wrong.
Yes that one is the same
Only other thing I can think of - if you have previously called route-deferred and never resolved it, that seems to mess up the state machine. I ran into this one time - when something fails, you generally want to redirect to another page (show an error, etc.
perhaps…not sure. I mean if you say you’re deferring and then fail to do so, I’m not sure who “owns” that
@mitchelkuijpers a when-let isn’t a good idea
Ah I copied it from the docs 😛
I don't remember the exact failure. It happened when I first switch to DR, and I realized if I call target-ready on the old route right before I switch routes, it fixed it.
Might this be a problem?
(defrouter LinkingPanelRouter [this {:keys [current-state]}]
{:router-targets [Issue]}
(case current-state
:initial (dom/div "What to show when the router is on screen but has never been asked to route")
:pending (ui-loader)
:failed (dom/div "Oops")
(dom/div "No route selected.")))
The first router target needs a ident, but it seems to load it for one second without the correct ident
@tony.kay since we're on the subject of DR, here's another one I just ran into Friday. I have nested routers and I route to the child one, and that route target is depending on data that should be loaded in the parent router. What I was expecting is that it would resolve the deferred route on the parent router before trying to route to the child, but that was not the case. I put in logging statements to confirm, and sure enough it calls will-enter on the parent, starts the load, then calls will-enter on the child, then the load finishes and calls target-ready on the parent. Not sure if that's intended behavior or a bug.
How do I handle network errors?
http://book.fulcrologic.com/#_detecting_errors_from_the_server
docs says about deprecated :network-error-callback
and I'm using a "custom" fulcro-http-remote
Should I do something l do something like it {:response-middleware (-> (fcn/wrap-fulcro-response) (network-error error-chan))}
?
@souenzzo that seems reasonable. For global errors, you generally want to log and maybe set something in app state that triggers a message in your UI (for instance, offline message for a mobile app that loses network). Then for handling errors in specific situations, I.e. where you know about the context and can take action, use the fallback mutation on your load.
You can do that with middleware, to a point. Well, technically with middleware all the way.
so, the middleware can rewrite the “query” and the “response”…so, you could change the query to one that would overwrite the “session info” that the login is based upon, and “make up” the tree of data.
that works as long as all you need is a state change with a refresh. You can also put the reconciler in a well-known atom and use that as a bit of a “hammer” for these kinds of circumstances…i.e. transact a new thing against the reconciler.
The websockets support has a hook that calls a functoin when network status changes, and typically the thing you provide does just those kinds of transactions.
My problem was that I did not call get-initial-state
on my LinkingPanelRouter
now it works like a charm
Note to @mitchelkuijpers and @mdhaney there is a known issue with dynamic router and state machines…really it is a design weakness in Fulcro: the dynamic router and state machine combo requires transactions that end up running is a hard-to-define (and see) order. There is a lot of setTimeout magic going on to prevent actual transactions from running truly “nested”, but that leads to conditions where the scheduling of setTimeouts happen “out of desired order”, leading to strange bugs. I’ve written an issue and RFC about this… That said, I’m using them pretty heavily with no complaints. On the “nested” deferred stuff. A route instruction will process all the way to the end (i.e. all routers in the target path will be told “will enter”). Any number of them can defer. Actual route display happens based on the state machine resolution of the actual paths. Technically a child could “finish” its routing before a parent…not that it would be on screen until the parent finished.
Makes sense. I was just making an unwarranted assumption about the ordering of route resolution, which is what I suspected but just wanted to clarify. Thanks!
yeah, there is no real need to force a sequential evaluation that I can see, so every router on the target path is told it will enter, and they can all defer in parallel.
@mdhaney perhaps your use-case is the more correct way, though. You state “the child depends on state the parent is loading”. Unfortunately I can see valid cases in both directions (parallel eval vs waiting to route the child). This is yet another use-case that would be solved by the new priority queue stuff I’ve written that RFC for: https://github.com/fulcrologic/fulcro/blob/feature/react-play/docs/RFCs/RFC-transaction-semantics.adoc With that support you’d be able to indicate that the child’s transaction doesn’t even start until the parent’s completes.