Skip to content

A re-frame effects handler for listening-for and then post-processing dispatched events

License

Notifications You must be signed in to change notification settings

day8/re-frame-forward-events-fx

Repository files navigation

Clojars Project GitHub issues License

re-frame-forward-events-fx

This re-frame library contains an Effect Handler, keyed :forward-events, which allows you to listen-for, and then post-process events, typically for higher-level control flow purposes (eg. coordination).

Quick Start Guide

Step 1. Add Dependency

Add the following project dependency:
clojars

Also requires re-frame >= v0.8.0

Step 2. Registration And Use

In the namespace where you register your event handlers, perhaps called events.cljs, you have 2 things to do.

First, add this require to the ns:

(ns app.events
  (:require
    ...
    [day8.re-frame.forward-events-fx]   ;; <-- add this
    ...))

Because we never subsequently use this require, it appears redundant. But its existence will cause the :forward-events effect handler to self-register with re-frame, which is important to everything that follows.

Second, use it when writing an effectful event handler:

(reg-event-fx             ;; note the -fx
  :my-event
  (fn [world event]       ;; note: world
    {:db   (assoc (:db world) :some :thing)          ;; optional update to db
     :forward-events  {:register  :coordinator1      ;;  <-- used
                       :events      #{:event1  :event2}
                       :dispatch-to [:coordinator 1]}}))

Notice the use of an effect :forward-event. This library defines the "effect handler" which implements :forward-events.

Tutorial

This effect handler provides a way to "forward" events. To put it another way, it provides a way to listen-for and then post-process events. Some might say it allows you to "sniff" certain events.

Normally, when (dispatch [:a 42]) happens, the event will be routed to the registered handler for :a, and that's the end of the matter.

But, with this effect, you can specify that a particular set of events be forwarded to another handler for further processing after normal handling. This 2nd handler can then further process the events, often carrying out some sort of meta level, coordination function.

The "forwarding" is done via a 2nd dispatch. The payload of this dispatch is the entire event dispatched in the first place.

:forward-events accepts the following keys (all mandatory):

  • :register - an id, typically a keyword. Used when you later want to unregister a forwarder. Should be unique across all :forward-event effects.
  • :events - the set of events for which you'd like to "listen"
  • :dispatch-to a vector which represents the template for the "further event" to dispatch. The detected event is provided (conj-ed) to this event template.

For clarity, here's a worked example. If you registered a ":forward-events" for event :a and you gave a :dispatch-to of [:later :blah], then:

  • when if any (dispatch [:a 42]) happened,
  • the handler for :a would be run normally. No change so far.
  • but then a further dispatch would be happen: (dispatch [:later :blah [:a 42]]). The entire first event [:a 42] is "forwarded" in the further dispatch.

Examples of use:

{:forward-events {:register    :an-id-for-this-listener
                  :events      #{:event1  :event2}
                  :dispatch-to [:later "blah"]}    ;; the forwarded event is conj to the end of this event vec
{:forward-events  {:unregister :the-id-supplied-when-registering}}

When necessary, the value of :forward-events can also be a list of maps, with each map either registering or unregistering.

Testing

To run the tests in a browser

lein dev

To run the tests with Karma (i.e. for continuous integration)

sudo npm -g install karma-cli
lein ci

About

A re-frame effects handler for listening-for and then post-processing dispatched events

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project