Fork me on GitHub
#fulcro
<
2021-04-13
>
Mateusz Mazurczak17:04:31

@tony.kay Hi, in a state machine, can you provide handler that is always run when entering particular state? Something like :entry handler

tony.kay18:04:11

See book. What’s supported is described there. “entering a state” is activate, and no, there is no automation at that point, but you’re already in a handler and can do whatever you want as a precondition yourself. Having handlers run on state transitions (without an explicit event) leads to bad behaviors like accidental infinite transition loops (handler transitions, runs a handler that transitions back, runs a handler that transitions again, etc.).

Mateusz Mazurczak19:04:25

Thank you Tony, i’ve saw the book I just didnt saw anything about that, that’s why I asked. But fully noted, no info in book = not implemented

Jakub Holý (HolyJak)21:04:15

@tony.kay I think that https://book.fulcrologic.com/#_initial_state_3 is incomplete and may lead to incorrect behavior. Correct pre-merge for a dynamically loaded component (with ident such as [:org/id <some id>] and :will-enter with dr/route-deferred a df/load! inside) that includes a router and, possibly, is itself under a router, should be in my experience something like:

:pre-merge     (fn [{:keys [data-tree state-map]}]
                    (assoc data-tree
                      :my/child-router   (merge
                                           (comp/get-initial-state MyChildRouter)
                                           (get-in state-map ; <--- this is crucial!
                                                   (comp/get-ident MyChildRouter {})))))
i.e. we need to keep the data of the router that already exist and only add an edge from the newly loaded component to the said router (or fall back to its init. state - actually I thought that this was likely unnecessary here if I provided :initial-state {:my/child-router {}} but that doesn't seem to be true). Alternatively, I could replace the :pre-merge with a custom post-mutation that would add this edge then transact dr/target-ready , I assume. What do you think? This has fixed, at long last, a long standing issue with my app where hard-reload of a page caused a report (under the :my/child-router above) to be displayed empty, because the parent router believed it was displaying a different (the default) route. Forgot to say: the issue I had seems due to timing. The top router's target-ready comes after the child's, and the pre-merge then overrides it.

👍 3
tony.kay05:04:51

So, you’re talking about a very special case, and yes, if you had a nested router that had already been in state you’re going to have some juggling to do. I’m not sure how to address that in the book any better than the Pre Merge chapter does, esp. around https://book.fulcrologic.com/#Premerge-mutation. I’m open to improvements to the section you’re pointing at, but the example you’re giving is very specific to an unusual composition in your own app.

Jakub Holý (HolyJak)08:04:48

Thank you! Is this problem so rare? I think the problem is (1) I have a nested router (where the ancestor gets ready only after the descendant one) and (2) the router is inside a dynamically loaded component. In particular, I dynamically load the selected Organization, which contains OrgDetails and the user can switch which details to show (each is a RAD report). Having a "Tabs" sub-component is common. Loading each "tab" as you select it and using the route to know which tab to show is perhaps less common but not that rare either? Or perhaps the problem is that I actually used the wrong tools to solve the problem (of loading data only as needed)? But I cannot see a different way to solve it....