fulcro

Eric Dvorsak 2025-08-29T07:43:32.062749Z

I have a root query in my component: [:root/current-course '_] I expect it to return the tuple: [:course/id 1] But occasionally it denormalizes and returns {:course/id 1 :course/name "my course"....} This causes occasional white screens when for instance destructure the ID out of the tuple I am running the latest fulcro cc3240fc with react 19 I did not run into this issue prior to switching to latest fulcro (the white screen) but will run tests to double check

Eric Dvorsak 2025-09-01T09:07:50.544399Z

Seems like it was caused by the combination of a root query [:root/current-course '_] wihtout attributes which normally returns a tuple (the ident) with an empty map as initial state {:root/current-course {}}

Eric Dvorsak 2025-09-01T09:09:21.012569Z

as a result in the latest version of fulcro/react 19 it sometimes resulted in the prop :root/current-course briefly being the denormalized value of current course from app-db instead of the tuple

tony.kay 2025-09-01T09:46:36.516649Z

In the Root component you should not use link queries (you are already AT the root). As far as initializing them…that’s an interesting case, but the db is initialized before any render…where did you have the initializer? On Root? or on the component with the link query?

Eric Dvorsak 2025-09-01T11:47:09.602669Z

It wasn't the Root component,

{:use-hooks? true
 :query [[:root/current-course '_]
           [:root/current-timeframe '_]]
 :initial-state {:root/current-course {}
                   :root/current-timeframe {}}}

tony.kay 2025-09-01T13:00:27.175509Z

Oh yeah, you should never try to initialize a root key from a non-root component

tony.kay 2025-09-01T13:00:42.979339Z

I should probably add some kind of check/compile error for that

Eric Dvorsak 2025-09-01T14:19:59.121139Z

Another interesting React 19 upgrade bug:

(defn on-saved [uism-env]
  (let [form-ident (uism/actor->ident uism-env :actor/form)
        props (get-in (::uism/state-map uism-env) form-ident)]
    (if (:ui/save-and-new props)
      (-> uism-env
          (uism/apply-action update-in form-ident dissoc :ui/save-and-new)
          (uism/transact [(create-new-question {...})]))
      uism-env)))

(uism/defstatemachine save-and-new-form-machine
  (let [base-machine draggable-form/draggable-form-machine
        handler-path [::uism/states :state/saving ::uism/events :event/saved ::uism/handler]]
    (-> base-machine
        (update-in handler-path
                   (fn [handler] (fn [env] (-> env handler on-saved)))))))
I updated the form-state-machine to support a "create and new" button, it simply calls on-saved after the :event/saved handler is called whe :ui/save-and-new is set. But with the fulcro/react-19 upgrade it doesn't work anymore, I get the warning that the I have unsaved changes and it routes back to the previous screen

Eric Dvorsak 2025-09-01T15:13:58.835889Z

I'm not sure I understand what uism/transact docstring is saying,

Just like `components/transact!`, but simply queues the transaction to be submitted after the handler completes.
   Usually you can use `apply-action` to do local state changes, and `trigger-remote-mutation` to do remote operations;
   however, sometimes external users of a state machine wish to supply ad-hoc operations that should be run by a
   state machine.

   NOTE: It is legal to side-effect in an event handler, but in general the desired operation is to defer
   the side effects (e.g. `comp/transact!`) until the handler has finished. Running, for example, a synchronous
   transact inside of a handler will not work as expected because the handler will finish after such a transaction
   and overwrite the changes to state that such a transaction caused.
does this mean that even though the transaction is queued to be submitted after the handler completes, it can still finish before the handler? also the exemple seems incomplete:
So, for example, someone might begin a state machine with:

   
(begin! this machine :id actors {:on-success `[(something-happened)])
which the state machine can save with `store`, and later look up with `retrieve`.

   `options` is as described in `components/transact!`.

Eric Dvorsak 2025-09-01T15:15:53.253359Z

Ok the docstring is actually saying that comp/transact! might finish before the handler

Eric Dvorsak 2025-09-01T15:16:53.382349Z

> queues the transaction to be submitted after the handler completes. seems like it no longer is the case with react-19 for uism/transact

tony.kay 2025-09-01T15:34:03.432029Z

I have no idea how that would break. React has absolutely nothing to do with UISM internals. You sure you’re not relying on someething sending an event that is tied to the UI that couples it to rendering?

Eric Dvorsak 2025-09-01T15:39:03.155609Z

I am only extending the :event/saved handler https://clojurians.slack.com/archives/C68M60S4F/p1756736399121139?thread_ts=1756453412.062749&cid=C68M60S4F

Eric Dvorsak 2025-09-01T15:50:17.970949Z

@tony.kay main thing I'm doing in that mutation is calling rad-routing/route-to!

Eric Dvorsak 2025-09-01T16:29:14.756129Z

so in form-allow-route-change the pristine state is not updated yet when route-to! calls it

Eric Dvorsak 2025-09-01T16:37:40.668709Z

@tony.kay So I found one strong sign of an issue: in the mutation if I check the content of :com.fulcrologic.fulcro.algorithms.form-state/forms-by-ident in '@state' even before calling rad-routing/route-to!, the pristine state which I get from @state has already been updated (which is expected). but inside of form-allow-route-change the pristine state which is obtained from (comp/props this) is not up to date and still contains the old value

Eric Dvorsak 2025-09-01T16:42:42.494149Z

I'll try to dig more later but my hunch is that target-denying-route-changes in fulcro is passing outdated props to allow-route-change? somehow

tony.kay 2025-09-01T17:57:56.647139Z

it could be that the react rendering in 19 has a different timing. This is why I try very hard to separate the behavior of the app from the rendering. unfortunately, the dynamic routing system does have some reliance on react’s rendering. It was a poor implementation choice on my part (from very long ago). This is also why today I’m leaning very much towards applications that leverage statecharts even for the routing, so that things have a much better overall semantics.

tony.kay 2025-09-01T17:58:26.831599Z

A patch to the dynamic routing system that eliminates the use of indexes (of UI components) might help…but it’s a rather complicated refactoring

Eric Dvorsak 2025-09-01T18:37:03.477639Z

@tony.kay in the meantime wdyt of https://github.com/fulcrologic/fulcro-rad/pull/141

tony.kay 2025-08-29T10:57:11.665249Z

Odd. I didn’t change anything internal, and I thought that normalization picks things apart and then merges the final bits into app state. Not sure why you’d see the map ever, unless some other bit of your code did so without normalizing