Fork me on GitHub
#re-frame
<
2020-09-17
>
Jason16:09:27

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/subscribes to :modal-data .

p-himik16:09:52

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?

p-himik16:09:09

Or at the very least, what is the condition to show the modal and what does ::open-edit-dialog actually do?

Jason16:09:45

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/subscribes to :edit-open. I can see how the timing might be tight for the subscription to propagate but am unsure how to ensure that.

p-himik16:09:23

The timing shouldn't be tight at all because subs propagate sync while dispatches work async.

p-himik16:09:38

Unfortunately I cannot say anything else without an MRE.

Jason17:09:56

I will put one together today. Thanks again for taking the time to reply.

👍 3
Jason02:09:21

i'm having real trouble constructing a meaningful MRE that isn't 80% of the app infra

p-himik06:09:42

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.

Jason23:09:07

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.

p-himik06:09:35

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.

p-himik06:09:06

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.

Jason23:09:23

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 mainview 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-datakey. • It then dispatches ::open-edit-dialogwhich 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-locationis called. 10% of the time the correct data shows up. Any advice gratefully accepted.

p-himik05:09:35

Not found. Missing index.html.

p-himik05:09:10

fork/form has some internal state that caches {:values {"name" "should never appear"}}. That's it, it has nothing to do with re-frame.

p-himik05:09:50

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.

Jason18:09:00

Thank you for taking the time to help. I understand your critique and will modify my coding style in the future

🙂 3