Fork me on GitHub
#re-frame
<
2021-02-07
>
Rob Knight08:02:15

I have an app divided between a ui namespace and a domain namespace. ui provides events to handle user interactions, and needs to trigger changes in domain - some of these changes involve updating the DB. It seems "clean" to implement a separate set of domain events, and have the UI events dispatch those using the :dispatch effect (or from within :fx). However, this seems to result in the domain events happening on the next cycle of the event loop, so there's a slight delay between the UI processing the event and the domain processing it, even though the required action is simply to update the DB. I could instead implement some regular fns in the domain namespace, which take a DB and return the updated DB, so instead of returning :dispatch [:domain/do-a-thing] from my UI events, I would return :db (domain/do-a-thing db), updating the DB immediately in the UI event. However, this means I can't easily decide to add side-effects to my domain events later on! What I really want is to be able to return :dispatch-sync [:domain/do-a-thing] so that my domain event happens synchronously, but this can't work as it's not possible to do dispatch-sync from inside an event handler. Is there a pattern for dealing with this that I have missed?

Rob Knight08:02:38

My first stab at this would be to have all of my UI events be reg-event-fx events, and wrap my return value in (domain/do-a-thing) allowing the do-a-thing fn to inject both new DB values and optionally additional effects. This would "mix in" the domain event with the UI event, so that both happen at the same time, but the UI event doesn't need to know or care about what DB updates or effects domain/do-a-thing is adding to it. It feels marginally less clean than having two separate events, but does make everything synchronous.

Rob Knight09:02:53

Interceptors would do something similar, but if I want to send extra parameters to the interceptor then I think I have to start storing them in the effects map that I return from the event, which seems weird.

p-himik09:02:14

You have pretty much outlined the available options. One other would be to implement your domain logic in a custom effect, but I wouldn't go that way. > there's a slight delay between the UI processing the event and the domain processing it Why is this important in the first place?

Rob Knight10:02:40

The simple answer is "to avoid UI flicker".

p-himik10:02:53

Right, I can see that. I would probably go with what you describe as your first stab. The only difference is that I would pass the new db value there separately to avoid having to fish it out of the whole :fx vector.

👍 3