Fork me on GitHub
#re-frame
<
2024-06-20
>
Jp Soares11:06:11

I want to update the url based on a subscription (or flow). The very straightforward way I thought about doing it would be to create an invisible component and update the url in there while I subscribe for the piece of data I need. But this is an antipattern, right? That would make my component not pure. Would be using effects (`reg-fx`)? If so, I would need to apply it to multiple events that might change the data I'm interested. I couldn't find the docs explaining it. I believe it's similar to cases where you want to log or send data do DataDog based on a subscription. What's the recommended way?

p-himik11:06:57

> I want to update the url based on a subscription Don't do it. > (or flow) IIRC flows can side-effect. If so, that would be reasonable. > But this is an antipattern, right? Indeed. I haven't really studied flows beyond the initial implementation so my memory might bu fuzzy but I think you can register a flow that runs and side-effects by itself, without you having to use it in a view.

p-himik11:06:55

Just skimmed through the docs - seems I'm wrong about side-effects in flows, so disregard that. One approach would be to have an effect, and event, and a global interceptor. The effect does the actual work of updating the URL. The event simply schedules that effect. The global interceptor monitors the desired values in the app-db and dispatches the event when needed. Alternatively, you can reverse the roles - change the URL and have some values in the app-db be determined by the URL.

Jp Soares11:06:47

Hum.. I'm reviewing Flow docs now and I don't think I can have an effect based on it. :thinking_face:

p-himik11:06:40

Yeah, that's what my second comment is about. :) So disregard subs and flows for this goal.

Jp Soares12:06:08

Sorry, I missed your second message when I wrote mine 😅 I never used a global interceptor, I'll check that, thanks.

Jp Soares12:06:37

> The global interceptor monitors the desired values in the app-db and dispatches the event when needed. Do you mean comparing :before app-db and :after and dispatching the :set-url-state if they are different?

p-himik12:06:02

Yep! Although probably not the whole app-db but rather some subset of values that should dictate the URL. But I myself definitely prefer to work with it the other way around, when the URL dictates the state. Makes navigating to e.g. a bookmark work by default.

p-himik12:06:22

If you're curious about that approach, you can check out kee-frame.

👀 1
Jp Soares08:06:27

It turns out an interceptor can't see a difference in app-db generated from a flow. The value I'm interested (that is generated by a flow) is always identical in coeffects' and effects' db. As far as I understood, this is happening because flow is a global interceptor that is calculated after the one I created. I'm trying to change the order my interceptor runs. Any suggestion?

p-himik09:06:18

@U02J388JDEG Any thoughts?

👀 1
Kimo09:06:53

We do handle the flow's db effect in a unique way, which is unfortunate. This issue seems like a consequence of that. It does seem like a problem we should solve at the framework level, not work around.

Kimo09:06:00

Let me think on it for a few days

Kimo12:06:31

@UBK8J929J I released https://clojars.org/re-frame/versions/1.4.4-SNAPSHOT. Haven't tested it much. I wrote down some implications that came to mind - there may be more that I haven't thought of, of course...

- Changed flows to calculate the new app-db earlier in the chain. 
      - Benefit: user-defined interceptors are aware of the post-flow app-db value.
      - Drawback: they can't access the value of app-db directly resulting from the event handler.
      - Drawback: they can't access flow-related effects like `:reg-flow`.

    - Added a :re-frame/pre-flow-db key to the context
      - This way, user-defined interceptors can still access the app-db value resulting directly from the event handler.

Jp Soares13:06:49

Ha, it's working now. Thank you very much @U02J388JDEG @U2FRKM4TW. I wasn't able to use the std-interceptor on-changes. Now it's working as expected. Awesome. 🙏:skin-tone-5: