Fork me on GitHub
#fulcro
<
2021-10-02
>
Jakub Holý (HolyJak)20:10:19

First time I use Fulcro Inspect to troubleshot why my app IS working. I suspect it got sentient when I wasn't watching and does what it guess I want, instead what I am (badly, on purpose) telling it to do 😹

😆 1
Jakub Holý (HolyJak)21:10:54

@tony.kay I would really appreciate your help, if you have a little time. I am trying and failing to make a demonstration for https://book.fulcrologic.com/#_composing_the_routers_state_into_the_parent I am even passing explicitly nil props to the router factory but inside the router, the props are not nil - they are {:current-state :routed, :route-factory #object[cljs.core.MetaFn], :pending-path-segment [], :router-state nil, :route-props nil} How is this possible? The component that owns the router is missing the edge to its data so I expect the router not to work but it does. Why? And how can I demonstrated the problem that requires adding the edge via pre-merge?? 🙏 ) the state of the router is like that (routed to that target) in the client DB but I expect the router not to see that due to the forced nil props Full code (88 lines with whitespaces) is here: https://github.com/holyjak/minimalist-fulcro-template-backendless/blob/example/routing%2Bpre-merge/src/com/example/ui.cljs

Jakub Holý (HolyJak)21:10:27

Update 1: Ok, I see now that :current-state comes not from the props but from the uism, which only depends on the router's class and not props. so that explains that. Similarly, current-route-class only depends on the router's dynamic query and not its props. Only :router-state and current-route props depend on props. Hm, but current-state should depend on id which depends on props and thus should be nil...?! Update 2: Ok so the props the defsc gets are indeed nil but not the props constructed inside the render-cases 's let .

Jakub Holý (HolyJak)21:10:16

Here is the core of the mystery: this router

(dr/defrouter PersonDetailsRouter [this myprops]
  {:router-targets [DefaultTarget AltTarget]
   :always-render-body? true}
  (println [:= current-state (uism/get-active-state this id)]))
(where current-state and id are defined by the defrouter macro) prints to the console:
[:= :routed nil]
but they should be equal because the former is defined by the latter at the first line of the router defsc body: https://github.com/fulcrologic/fulcro/blob/c840483be0c635825b47b8f6434c98de093bf83c/src/main/com/fulcrologic/fulcro/routing/dynamic_routing.cljc#L828

tony.kay21:10:36

I can chat in a bit...working on something

👍 1
🙏 1
Jakub Holý (HolyJak)21:10:33

No hurry! I really need to go to bed now anyway. Thank you!

tony.kay04:10:41

So, the defrouter isn't a pass-through component (like RAD forms or reports, for example), but is instead a wrapper around all sorts of complexity that it is simplifying. The props you get in the body of the router are not the props you pass to it, as you've seen. It passes constructor props to tell you about the current state of the state machine, etc. So, some of the things in the props of a router will never be nil (as you found) because there is derived stuff going on inside. However, the router will of course malfunction if you don't pass it's props to it. In general a defrouter isn't the best thing to use for a simple demo of something like pre-merge. You should not use current-state without destructuring it from props. It's an oversight on my part that that compiles at all, since current-state is not obviously in scope in any way...so definitely don't advertise that as something you can/should do. It's a bug that you can compile current-state in the body without destructuring it. If you're passing nil props to the router, then it will not get the UISM data at all; however, some of the functions it uses, as you've seen, need only this to be functional. Ultimately I'm not sure what you're trying to do in your example code, but purposely misusing a macro isn't likely to be particularly illuminating. With always-render-body? set to true, the real code you're running for the body is on line 799 of dynamic_routing.cljc. The class and factory will be figured out because that grabs things from the low-level state and the query itself. The other bits rely on props, and will end up nil as a result.

Jakub Holý (HolyJak)06:10:05

Thank you! I'm not trying to demonstrate pre-merge but why you must use pre-merge to fix the link to a router if it is inside a dynamically loaded component - see https://book.fulcrologic.com/#_composing_the_routers_state_into_the_parent But Im not able demonstrate the problem that section describes because the ego router works anyway. Of course I do not intend to use the non-destructed current-state in any real code. I only used it here to understand the mystery of why it is not nil. So this is the real question I have to you: why is current-state, and thus also :current-state, not nil?! How can I demonstrate the problem described in the book? Thank you!

Jakub Holý (HolyJak)12:10:52

(I've updated https://github.com/holyjak/minimalist-fulcro-template-backendless/blob/example/routing%2Bpre-merge/src/com/example/ui.cljs to be what I actually want it to be. Because if the missing link, I expect the router to have the state nil and to display the default target. Yet it is routed and displays the Alt target.)

Jakub Holý (HolyJak)21:10:16
replied to a thread:@tony.kay I would really appreciate your help, if you have a little time. I am trying and failing to make a demonstration for https://book.fulcrologic.com/#_composing_the_routers_state_into_the_parent I am even passing explicitly `nil` props to the router factory but inside the router, the props are not nil - they are `{:current-state :routed, :route-factory #object[cljs.core.MetaFn], :pending-path-segment [], :router-state nil, :route-props nil}` ** How is this possible? The component that owns the router is missing the edge to its data so I expect the router not to work but it does. Why? And how can I demonstrated the problem that requires adding the edge via pre-merge?? :pray: **) the state of the router is like that (routed to that target) in the client DB but I expect the router not to see that due to the forced nil props Full code (88 lines with whitespaces) is here: https://github.com/holyjak/minimalist-fulcro-template-backendless/blob/example/routing%2Bpre-merge/src/com/example/ui.cljs

Here is the core of the mystery: this router

(dr/defrouter PersonDetailsRouter [this myprops]
  {:router-targets [DefaultTarget AltTarget]
   :always-render-body? true}
  (println [:= current-state (uism/get-active-state this id)]))
(where current-state and id are defined by the defrouter macro) prints to the console:
[:= :routed nil]
but they should be equal because the former is defined by the latter at the first line of the router defsc body: https://github.com/fulcrologic/fulcro/blob/c840483be0c635825b47b8f6434c98de093bf83c/src/main/com/fulcrologic/fulcro/routing/dynamic_routing.cljc#L828