This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-05-26
Channels
- # announcements (7)
- # babashka (42)
- # beginners (349)
- # chlorine-clover (9)
- # cider (16)
- # circleci (2)
- # clj-kondo (6)
- # cljs-dev (61)
- # cljsrn (15)
- # clojure (95)
- # clojure-europe (11)
- # clojure-italy (2)
- # clojure-nl (4)
- # clojure-spec (4)
- # clojure-uk (24)
- # clojurescript (21)
- # conjure (2)
- # core-async (8)
- # cursive (12)
- # datascript (2)
- # emacs (4)
- # exercism (1)
- # figwheel-main (86)
- # fulcro (27)
- # graalvm (4)
- # helix (36)
- # hoplon (3)
- # interop (44)
- # kaocha (6)
- # lein-figwheel (4)
- # malli (7)
- # meander (9)
- # off-topic (95)
- # pathom (33)
- # pedestal (13)
- # re-frame (20)
- # reitit (3)
- # shadow-cljs (102)
- # tools-deps (14)
- # xtdb (16)
hi
I have a little question regarding best practices in re-frame please especially on "sync"-ing data between local app-db
and a remote datasource
, a db for e.g
does it make sense for a example in a typical scenario where I am adding HTTP POST-ing to a remote /api/resource
to have a :dispatch-n
in a an event-handler to dispatch the POST and right behind it a GET to fetch and refresh the local app-db
like so :
(rf/reg-event-fx
:add-resource
(fn [_ [_ new-resource]
{:dispatch-n [[:http/post "/api/resource" new-resource] ;; adding a resource
[:http/get "/api/resource"]]})) ;; sync-ing and refreshing local app-db
thanks in advanceEven if your :http/post
event handler uses only synchronous effects (which I don't think is possible), I still wouldn't use that code because error handling becomes impossible. What if the POST request was unsuccessful, how do you handle that?
Expanding a bit more of synchronous effects. Let's put re-frame aside for now. When you make an HTTP request with a browser JS, you have to provide a callback that will be executed at some point in time when the request returns some response. It doesn't matter whether it's an explicit callback, and async function with a continuation, or promise chaining. It means that the code that goes after the one that issues the initial request will be executed asynchronously with the request itself. Meaning, you cannot guarantee the order in any way.
so do you then suggest that the "refresh" dispatch should be for e.g sent from the on-success-handler of the http post ?
I keep noticing in various components that my subscriptions seem to pass through the subscription ID rather than the correct value. So like, if I (let [sub (rf/subscribe [:data/current-user])] ,,,)
, and call (prn @sub)
in my component, I will sometimes see [:data/current-user]
instead of the correct value.
Is this a known issue? Am I holding it wrong somehow?
I simplified some of the details in my question above, but here's an actual subscription that's exhibiting this behavior:
(rf/reg-sub ::current-student-id :current-student-id)
I reasoned that :current-student-id
is equivalent to (fn [db] (:current-student-id db))
, but maybe that's not a valid shortcut for some reason I don't understand?
weird
cljs.user> (rf/reg-sub :thing :thing)
#object[re_frame$subs$subs_handler_fn]
cljs.user> (rf/subscribe [:thing])
#<Reaction 1153: [:thing]>
cljs.user> @(rf/subscribe [:thing])
[:thing]
Yeah that's what I'm seeing. I'll note that my example is slightly different in that I have a ::
prefix on the sub name. But yeah.
subscriptions are 2-arity functions:
(fn [db sub-vec]
,,,)
so it’s passing in (:thing db [:thing])
and if db
doesn’t have :thing
, it returns [:thing]
Ahhhh…makes perfect sense, thanks @lilactown!