Fork me on GitHub
#re-frame
<
2024-03-25
>
lwhorton23:03:36

hmm... is it possible to make a reg-fx handler receive the database? is that a bad idea? the gist of what i'm getting at is:

(rf/reg-fx :router/navigate nav-fx)

...

(defn nav-fx [app-db cofx-map] ...)

(rf/reg-event-fx (fn [...] {:fx [[:router/navigate {:route ... :other-args ..}]]})
and i'm looking for a non-silly way to give my nav-fx access to the db. i would prefer not having to provide the db through each and every reg-event-fx that wants to utilize the :router/navigate 'dsl'. dereffing the db is an option, i suppose. it kind of feels like i'm thinking about my problem incorrectly though, if this isnt in the documentation and hasn't been considered already

p-himik02:03:56

You can access re-frame.db/app-db directly. But it would be using a private API. Why does a plain navigation fx need the whole app-db?

lwhorton13:03:19

That's what I'm doing at the moment- just derefing the db. It doesn't really need the whole db, it only needs a slice that contains routing information. I wasn't able to find an existing mechanism for injecting a subscription into an fx, or something like that In that fx I am doing a bunch of work to manage parent / child relationships of routes. The hope is to try and decouple a caller (who wants to navigate to :XYZ at id ABC) from the routing table (where :XYZ might require 3 IDs in its path, in addition to ABC)

valerauko14:03:02

Does this routing information have to live in the app-db?

lwhorton15:03:53

technically no, but i'm using reitit's fe as the router. its getting plugged into the whole reframe architecture sort of like described here: https://gist.github.com/vharmain/a8bbfa5bc601feba0f421959228139a1 but i think that's beside the point. i'm more curious if there's a standard mechanism for a reg-fx effect to get handed a db, or slices of a db, or a sub, perhaps through injection or cofx injection or some similar mechanism. the crux of it is just this deref, which feels weird and ugly:

(defn nav-fx [config]
  #_(def c config)
  (let [_ (validate-nav-config config)
        router (deref r/router)

        ;; this is super side-effecty, but that's entirely the point of reg-fx
        db (deref rf/app-db)
        current {:route (:router/current-route db)
                 :path-params (:router/path-params db)
                 :query-params (:router/query-params db)}
        config (->route router current config)
        {:keys [route path-params query-params]} config]
    (rfe/push-state route path-params query-params)))
that ->route is doing a lot of work which is dependent on the current route and the next/proposed route

lwhorton15:03:24

from what i've been able to find in the docs, it doesn't seem like there's a built-in mechanism for getting more data into a nav-fx. that's fine by me, i just dont want to invent my own thing if i dont have to

p-himik15:03:12

The standard mechanism is to pass the db as a parameter.

valerauko15:03:39

I don't really understand what you're trying to achieve, but I have reitit+reframe in this project https://github.com/valerauko/kitsune/tree/main/web/src/kitsune Maybe routes.cljs and the routes/ folder can help you?

valerauko15:03:18

Personally I prefer to use the browser for the navigation and have the router/cljs react to that (reitit's on-navigate callback)

lwhorton15:03:33

The standard mechanism is to pass the db as a parameter.ah, okay. that's reasonable- i just didnt want my consumers of the routing fx to always have to remember to forward that information too

...
(reg-event-fx 
  :some-routey-thing-happened 
  (fn [cofx args] 
    {:fx [[:router/navigate {:route :other-route :path {...} :query {...} :current-route (router-db-interface/current-route 
(:db 
cofx)]]}))

vs

[[:router/navigate {:route :other-route :path {...}}]
oh man i'm really struggling to write code since slack changed some formatting defaults

p-himik15:03:31

If you have a lot of events dealing with navigation, I'd extract adding the whole :router/navigate fx vector into its own function:

(reg-event-fx :x
  (fn [{db :db} args]
    (-> {:db db
         :fx [whatever]}
        (add-navigation-fx ...))))

lwhorton15:03:37

i wonder if i should make myself an interceptor for route-handling event-fx. or maybe even a reg-event-route that comes with a pre-canned interceptor to add navigation details

lwhorton15:03:50

or, you know, just deref the app-db

p-himik15:03:18

All are viable options.

lwhorton16:03:28

sigh i'm so silly. almost nowhere in my app do i directly return an :fx [[:router/navigate]]. i'm always dispatching an event :router/navigate and that reg-event-fx can handle putting the db's router state into the reg-fx config map. i'll also put up an interceptor that fully prevents consumers from directly utilizing the :fx :router/navigate, and force them to always use the event instead. all this took about 3h of thinking, and 10m of implementing. re-frame really is genius.

😄 1
👍 1
🚀 1