Fork me on GitHub
#fulcro
<
2023-03-17
>
Eric Dvorsak17:03:44

I noticed that the ::dr/current-route of a dynamic router contains the props of the component being routed to. Is there a way to get the active leaf of a parent dynamic router to access these props from the parent? Eg: ParentRouter has ParentLeaf with a ChildRouter that has ChildLeaf, I want to be able to use the props of ChildLeaf in ParentLeaf

Eric Dvorsak17:03:27

The problem I'm trying to solve is that ParentLeaf is a header that displays some info, but the ChildLeafs are forms for different kind of entities, whose ident can resolve the attributes that the header in parentLeaf needs. When the url of a child is accessed directly the ident of the parentLeaf is not in the path params

tony.kay21:03:27

The props are always a tree. If you have the parent props, then you also have the leaf.

tony.kay21:03:01

in other words, the current route props are the tree of props of the current parent/child

tony.kay21:03:15

no need to look for an ident…you have a denormalized tree.

Eric Dvorsak22:03:13

I think I understand that, my issue is that the props needed by the parent are not loaded at that point, but the parent can do a load if it finds the ident of leaf

Eric Dvorsak22:03:26

I am able to get what I want with the following snippet in a mutation done in the will-enter of the parent

(let [state @state]
            (loop [new-router-k router-k]
              (let [[k v :as ident] (or (get-in state [::dr/id new-router-k ::dr/current-route])
                                        (get-in state [::dr/id new-router-k ::dr/pending-route :target]))]
                (if (= ::dr/id k)
                  (recur v)
                  ident))))
but for this to work I cheated and my ChildComponent with the ChildRouter as an ident like this (fn [] [:com.fulcrologic.fulcro.routing.dynamic-routing/id ::ContentRouter])

tony.kay16:03:45

In general I would not recommend tying loads to things this way. If you have a complex scenario, I highly recommend you put a UISM or statechart around it, and control it that way. Treat DR as a ui-only concern most of the time. The side-effect integration in DR is for very simple cases (start something when a route is entered), and should use the DR lifecycle hooks. Putting I/O in the router itself is seriously discouraged.

❤️ 2
tony.kay16:03:56

and popping idents in state that point to “nowhere” is also a pretty bad idea

tony.kay16:03:00

Drive your UI and I/O from your logic. Logic drives data shape, which drives rendering as a pure function. Do not invert that except in very simple cases, or where there is literally no other way (e.g. focus an input). You’re sort of in a middle ground here. The logic of the DR is what you’re trying to sort of hook into, but it’s a really gray area. You’re trying to do something in a way it wasn’t designed for, which is making kind of a mess.

❤️ 2
Eric Dvorsak16:03:17

Thanks for the advice I'll look into using a uism to manage the initial loading then. I suppose what Im doing now is akin to it. When current-course (my parent is a Course) is set I route immediately in the parent, when not i defer to a mutation that looks into the routers to find the current target and load the parent info from that target and sets the current course. On parent will unmount I unset the current-course

Eric Dvorsak20:03:33

In the fulcro book example here: https://book.fulcrologic.com/#_router_react_lifecycle_methods the function uism/current-state is used but it doesn't exist, was it meant to be uism/get-active-state?

tony.kay21:03:31

Yes, the book is wrong. There is a prop called :current-state that is passed in. See the docstring of defrouter.