Slightly wiser newb here. I seem to have a timing issue with what I thought was a simple, non-controversial event handler. Here it is:
(rf/reg-event-fx
::edit-widget
(fn [{db :db} the-data]
(prn "edit-widget" the-data)
{:db (assoc db :modal-data (last the-data)) <= (1) this data appears in the db
:dispatch [::open-edit-dialog]})) <= (2) after this happens
To my surprise, nine times out of ten, the form appears (2) before the db mutation (1) is applied. I thought I was on solid ground here because the order of fx execution is clearly stated in the docs (`:db` first, then undefined). Any help appreciated.
Edited to add: FWIW, the form rf/subscribe
s to :modal-data
.i'm having real trouble constructing a meaningful MRE that isn't 80% of the app infra
Given the issue description, that sounds really suspicious - as if it's that infra that creates the erroneous behavior and not re-frame. :) Do what you can and send the link - I'll try to take a look when I have time.
Hello, I made a minimal project to demonstrate my issue
https://github.com/jasonh-logic2020/ui
All the action is in ui/views/locations.cljs
. All three of the defined forms have the same issue: the old :modal-data
shows up in the form 90% of the time and the freshy-assoced data shows up 10% of the time.
Please let me know if there's anything else I can provide and thanks again for taking the time to reply.
A small thing that I immediately noticed - both package.json
and package-lock.json
are in .gitignore
. Don't do that. Commit both files, always.
And now that I got a bit deeper... what am I looking at? It doesn't even look like an attempt to create a minimal example - it has more than 1kloc! Its deps.edn
is almost 250 lines! Is the ui/components/copiright.cljs
really related to the problem? Doesn't look like it. ui/utils.cljs
is not used by anything. Why does it need all that Material UI crud when your problem is with re-frame itself? Your original code is not even there - sure, I could find it, but the onus shouldn't be shifted on me. I could go on, but I hope you get the picture.
Please, try to reduce it. It shouldn't be more than a 100loc. It shouldn't have any dependencies other than re-frame related ones. It shouldn't have a 250loc deps.edn
.
Okay, I got rid of everything except the view and form to show the issue. It's still bigger than you wanted, but I left the UI in because the actual order of UI events is part of the story. I hope this is okay.
All the action is in ui.views.locations
• The edit dialog is included in the main
view at Line 293.
• ::edit location (Line 60) is called when the button is pressed (Line 286).
• It puts the event data in the app db :modal-data
key.
• It then dispatches ::open-edit-dialog
which displays the dialog
• The dialog has already subscribed to :modal-data
in Line 232 for its :initial-values
.
Roughly 90% of the time, the form is displayed with what was in :model-data
before ::edit-location
is called. 10% of the time the correct data shows up.
Any advice gratefully accepted.
Not found. Missing index.html.
fork/form
has some internal state that caches {:values {"name" "should never appear"}}
. That's it, it has nothing to do with re-frame.
If you'd only try to create a proper MRE, you would've found it yourself because the issue would disappear as soon as you'd remove fork/form
.
Thank you for taking the time to help. I understand your critique and will modify my coding style in the future
Even if :db
was second, it should still work as you expected simply because :dispatch
doesn't call the handler function immediately - it just puts the event at the end of the queue.
I have no idea why you see what you see. Can you create a minimal reproducible example?
Or at the very least, what is the condition to show the modal and what does ::open-edit-dialog
actually do?
Thanks for replying. This is a material-ui + fork app. Here is ::open-edit-dialog
(with my debugging prn included):
(rf/reg-event-db
::open-edit-dialog
(fn [db _]
(prn "open edit-dialog" (:modal-data db))
(assoc db :edit-open? true)))
The form contains a material-ui Dialog component whose :open
parameter rf/subscribe
s to :edit-open
.
I can see how the timing might be tight for the subscription to propagate but am unsure how to ensure that.The timing shouldn't be tight at all because subs propagate sync while dispatches work async.
Unfortunately I cannot say anything else without an MRE.
I will put one together today. Thanks again for taking the time to reply.