This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-09-06
Channels
- # announcements (12)
- # asami (3)
- # babashka (59)
- # beginners (20)
- # biff (1)
- # calva (87)
- # cherry (8)
- # clj-kondo (41)
- # clj-together (4)
- # cljdoc (5)
- # cljfx (4)
- # cljs-dev (2)
- # cljsrn (6)
- # clojure (63)
- # clojure-europe (22)
- # clojure-nl (1)
- # clojure-norway (35)
- # clojure-uk (4)
- # clojurescript (5)
- # conjure (2)
- # datalevin (4)
- # datascript (8)
- # datomic (16)
- # events (1)
- # figwheel-main (1)
- # fulcro (9)
- # hyperfiddle (4)
- # introduce-yourself (1)
- # jobs (3)
- # kaocha (10)
- # lambdaisland (2)
- # lumo (7)
- # nbb (1)
- # off-topic (29)
- # pathom (15)
- # re-frame (80)
- # releases (1)
- # remote-jobs (4)
- # shadow-cljs (13)
- # spacemacs (9)
- # sql (25)
- # squint (32)
- # tools-deps (6)
- # uncomplicate (6)
- # xtdb (15)
What is the difference between using :fx
and :dispatch-n
?
{:fx [[:dispatch [:event1]]
[:dispatch [:event2]]]}
{:dispatch-n [[event1]
[event2]]}
:fx
is for any effects (including dispatching other events, but also your own custom effects): https://github.com/day8/re-frame/blob/master/docs/Effects.md
using fx rather than dispatch-n is preferred according to API docs: https://day8.github.io/re-frame/api-builtin-effects/
Hi guys! Do we have a workaround now for calling a subscription just once and not keeping it in the cache?
If you call it in a reactive context, it will be removed from the cache right when the view is unmounted.
and what about the not-reactive context?
You can write your own version of subscribe
that uses private but simple API of re-frame.
I wrote below code , and I am not getting why event dispatch1
is not calling after called with dispatch-sync ! , and I am getting the error no handler registered for effect:
, but this works if I define it in :dispatch , any reason ?
(reg-event-db
:dispatch1
(fn [db [_ resp]]
(println "----2----")
))
(reg-event-fx
:event1
(fn [db [_ resp]]
(println "------1----")
{:dispatch-sync [:dispatch1 resp] }))
> no handler registered for effect
I assume it's followed by :dispatch-sync
?
dispatch-sync
exists in re-frame itself as a function. But it doesn't exist there as an effect.
@U2FRKM4TW thanks for responding! Do you mean the way I am calling :dispatch1
is not right ?
Nope. Effects and functions are completely different things.
The fact that there's a function re-frame.core/dispatch
and the fact that there's an effect :dispatch
registered in re-frame.fx
are completely unrelated.
There's also a :dispatch-later
effect, but there's no dispatch-later
function.
ohh ok, what if I have the scenario, where one of my event is depends on another, How can I achieve it ?
Depends on what you mean by "depends". :) Ideally, you would just refactor your code in such a way so that dependent functionality is tied together by composing functions.
I am learning interceptor and wrote below code , when the after returns (assoc-in context [:effects :db] new-db)
it does not giving expected result where as if I return context
it is working as expected! What am I doing wrong ?
(def trim-event
(re-frame.core/->interceptor
:id :trim-event
:after (fn [context]
(let [{:keys [db ]} (:coeffects context)
new-db (assoc db :J "J")
_ (println "----E---"(keys (:effects context))" "(keys (:coeffects context)))]
(assoc-in context [:effects :db] new-db)))))
(reg-event-db
:even1
[trim-event]
(fn [db [_ resp]]
(println "------1----")
(-> db
(assoc-in :t "t")
(assoc-in :k "k"))))
You're getting a coeffect and returning an effect in your interceptor.
Since it's :after
, you should probably stick to just effects and ignore coeffects unless there's no db coeffect.
here context is assoc with :effect :db but the return will contains both coeffect and effect right ? also I refereed code from https://github.com/jgdavey/minesweeper/blob/main/src/main/minesweeper/app.cljs#L185 which I did it in similar way
> but the return will contains both coeffect and effect right ? Yes. But the code that you link to does not take db from coeffects - it does so from effects. And unconditionally, so it assumes that the corresponding event handler always returns the db. Unless something has changed in re-frame that I haven't seen.
so iāve created the :on-failure reg-event-fx and here as well define a :http-xhrio with a :on-success and :on-failure
however.. this time, I see the API call getting fired (local server), but the :on-success call doesnāt seem to get called š
(reg-event-fx :failure-http-using-token (fn [{:keys [db]} [ result]] ; retry grabbing token with refreshtoken {:db db :http-xhrio {:method :get :uri (utils/flow-api-url) :params {:r @(subscribe [:refresh-token])} :format (ajax/json-request-format) :response-format (ajax/json-response-format {:keywords? true}) :on-success [:save-token] :on-failure [:failure-http-result]}}))
(reg-event-fx :save-token tokens-interceptor (fn [{:keys [db]} [_ return-json]] (js/alert return-json) (let [data (:data return-json)] {:db (assoc db :tokens {:token (:accessToken data) :refreshtoken @(subscribe [:refreshtoken])}) :dispatch [:set-active-nav :settings]} )))
very strange behavior, because previously i did an assoc-in db :tokens to only update :token, but then my :refresh-token was wiped out
(interceptor that saves the tokens to localstorage, somehow wiped it in localstorage, only saving :tokens :token)
First of all, just in case, I'm gonna mention that using @(subscribe ...)
in an event handler is an anti-pattern. If you open the JS console, there will be warnings from re-frame about it.
Another thing worth pointing out is that js/alert
is blocking. I don't really know how you test it, but until you close that pop-up, none of the following code will be executed.
Apart from that, I don't notice anything obviously wrong. But I would definitely suggest using js/console.log
instead of js/alert
to debug things.
(reg-event-fx :save-token tokens-interceptor (fn [{:keys [db]} [_ return-json]] (js/alert return-json) (js/alert (:tokens db)) (js/alert db) (let [data (:data return-json)] {:db (assoc-in db [:tokens :token] (:accessToken data)) :dispatch [:set-active-nav :settings]})))
I would still use js/console.log
- it does preserve order. It even supports groups with js/console.group
and js/console.groupEnd
.
the return-json: provides the result the (:tokens db) is NULL š the db seems to only contain the map of :token en :refresh-token
(defn tokens->localstore [tokens] (tap> tokens) (let [actual-tokens (:tokens tokens)] (.setItem js/localStorage ātokensā (str actual-tokens))))
Well, there you have it - the db
there is actually (:tokens app-db)
because of that path
interceptor.
A path
interceptor replaces the :db
coeffect in its "before" stage and puts the resulting effect in the right place it its "after" stage.
hmm, for some reason (js/console.log) doesnāt seem to be working for me in Safari - no output
iām confused then why this works as expected: (reg-event-fx :save-tokens tokens-interceptor (fn [{:keys [db]} [_ return-json]] ; (js/alert (str āSUCCESS: ā return-json)) (let [data (:data return-json)] {:db (assoc db :tokens {:token (:accessToken data) :refreshtoken (:refreshToken data)})})))
> hmm, for some reason (js/console.log) doesnāt seem to be working for me in Safari - no output
Maybe js/console.log
is overwritten by something - you can check by executing console.log(1)
on a different web page.
If that doesn't work, maybe your JS console filtering is set to something. I don't use Safari myself so can't tell.
> iām confused then why this works as expected:
My bets are on it not actually working like it should. In the end, it will result in the db having 2 nested :tokens
.
i really thought, looking at the re-frame todomvc that it would do everything after the event ha, not before