This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-04-19
Channels
- # announcements (24)
- # asami (25)
- # babashka (17)
- # beginners (99)
- # bitcoin (1)
- # calva (2)
- # cider (6)
- # cljs-dev (4)
- # clojure (88)
- # clojure-australia (3)
- # clojure-europe (23)
- # clojure-france (6)
- # clojure-nl (5)
- # clojure-uk (31)
- # clojured (1)
- # clojurescript (6)
- # clojureverse-ops (1)
- # datomic (28)
- # depstar (18)
- # emacs (11)
- # events (1)
- # fulcro (21)
- # graalvm (4)
- # graphql (7)
- # heroku (1)
- # jackdaw (18)
- # joker (3)
- # kaocha (1)
- # lsp (1)
- # malli (13)
- # meander (4)
- # off-topic (12)
- # pathom (14)
- # pedestal (2)
- # podcasts-discuss (1)
- # re-frame (37)
- # reagent (17)
- # reitit (9)
- # shadow-cljs (44)
- # xtdb (17)
Is there a way to detect an error in an effect? I would like to add a custom error handler for the effect that I don’t control and was wondering if this was possible?
There's not built-in functionality, but you could wrap that third-party effect handler with your own error handling by first retrieving it with (re-frame.registrar/get-handler :fx that-effect-id)
and then just calling it as a function within your own effect handler
Do note that re-frame.registrar/get-handler
is not a public API.
thanks, nice option
Thanks @U0CC9TJ11 I have updated re-frame-template to use the latest re-frisk release.
it doesn't show views names in the demo because of optimization, but they will be shown in dev
Hi everyone, what's the best practice for checking for mistakes in events and subscriptions? For example, I recently deleted a subscription that was still being used (by accident of course). It would be great to set up something that automatically alerts me to these inconsistencies in the future!
If you mean something like static analysis to detect such things, then maybe #clj-kondo could be used, or at least something that it uses itself.
But it won't be robust because you can create and use subscriptions and events dynamically.
@U01BRM3MQET I am in no way who you should go to for best practices, but anything you can tie to a var you can get compiler error if you mess up
(def get-stuff [db id]
...)
(rf/reg-sub
::stuff
(fn [db id]
(get-stuff db id)))
(defn subscription:get-stuff
[id]
(rf/subscribe [::stuff id]))
Actually, tracking missing events/subs should be pretty straight forward, as you get subscription nil
and event not found
errors logged in the console.. I’ve never had to spend more than a few seconds to realize what was missing
(def event:event-name ::event-name)
(defn event-name [args]
[event:event-name args])
(defn handler:event-name
[{:keys [db]} args]
{:db ...
:fx ...})
(rf/reg-event-fx
event:event-name
handler:event-name)
Yeah, but that works only if something does happen that uses that sub or event. If you never click a particular button and don't have a test for it, it might end up being sent to the production. (answering to Lu)
@U3JH98J4R very interesting... A little crazy but maybe that's the genius behind it :P
Let me guess - so you always require
the necessary namespace with the right calls to reg-event-*
? :)
I do something similar but more lazy and less robust:
(ns some.stuff
(:require [re-frame.core :as rf]))
(rf/reg-sub ::value
(fn [db _]
(:value db)))
(rf/reg-event-db ::set-value
(fn [db [_ new-value]]
(assoc db :value new-value)))
(ns other.things
(:require [re-frame.core :as rf] [some.stuff :as stuff]))
(defn input []
[:input {:value @(rf/subscribe [::stuff/value]), :on-change #(rf/dispatch [::stuff/set-value %])}])
Thats part of it, but more importantly we only ever use :db and :fx so we can compose event handlers and write tests like
(let [process (custom-compose
#(handler:focus-on-field % (focus-on-field))
#(handler:typed-in-field % (typed-in-field "a"))
#(handler:typed-in-field % (typed-in-field "b")))]
(is (= (:db (process (...initial db state)))
...asserted db state...))
(is (contains-some-effect-we-want-to-assert
(:fx (process (...initial db state))))))
and moving towards banning use of :dispatch within event handlers so we can always make these assertions and state changes happen "atomically"
is this
> (def event:event-name ::event-name)
some kind of namespacing by convention, i.e. the use of :
in the symbol there? @U3JH98J4R
might macro it up at some point if the pattern holds, but for now biting the bullet of typing so we don't get hard locked in
so for @U2FRKM4TW's example we would do this
;; Events
(def event:user-typed ::user-typed)
(defn user-typed [text]
[event:user-typed text])
(defn handler:user-typed
[{:keys [db]} [_ text]]
{:db (update db ::model/page-state
:user-input assoc text)
:fx []})
(rf/reg-event-fx event:user-typed handler:user-typed)
;; view
(defn input [{:keys [user-input]}]
[:input {:value user-input
:on-change #(rf/dispatch (events/user-typed %))}])