¶
Question¶
Does re-frame allow me to register global interceptors? Ones which are included for every event handler?
Answer (v1.0.0 onwards)¶
Yes, re-frame provides an API for registering global interceptors.
The following code creates a global interceptor to keep a track of all events:
;; We'll be recording events into this atom
;; The most recent events will be at the front of the list.
(def event-store (atom (list)))
(defn keep-last-20
[existing new-one]
(take 20 (conj existing new-one)))
;; this interceptor will collect events and add them to the atom above
(def event-collector
(re-frame.core/->interceptor
:id :event-collector
:before (fn [context]
(swap! event-store keep-last-20 (re-frame.core/get-coeffect context :event))
context)))
;; register this global interceptor early in program's boot process,
;; using re-frame's API
(re-frame.core/reg-global-interceptor event-collector)
Answer (prior to v1.0.0)¶
Prior to v1.0.0, re-frame provided no API to directly support this feature, but there are ways of making it happen.
Let's assume you have an interceptor called omni-ceptor
which you want
automatically added to all your event handlers.
You'd write a replacement for both reg-event-db
and reg-event-fx
, and get
these replacements to automatically add omni-ceptor
to the interceptor
chain at registration time.
Here's how to write one of these auto-injecting replacements:
(defn my-reg-event-db ;; a replacement for reg-event-db
;; 2-arity with no interceptors
([id handler]
(my-reg-event-db id nil handler))
;; 3-arity with interceptors
([id interceptors handler]
(re-frame.core/reg-event-db ;; which uses reg-event-db
id
[omni-ceptor interceptors] ;; <-- inject `omni-ceptor`
handler)))
NB: did you know that interceptor chains are flattened and nils are removed?
With this in place, you would always use my-reg-event-db
instead of the standard reg-event-db
:
(my-reg-event-db
:event-id
(fn [db v]
...))
And, hey presto, you'd have your omni-ceptor
"globally" injected.