Fork me on GitHub
#re-frame
<
2020-05-26
>
kaffein15:05:32

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 advance

p-himik15:05:45

Even 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?

p-himik15:05:36

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.

👍 4
kaffein15:05:40

so do you then suggest that the "refresh" dispatch should be for e.g sent from the on-success-handler of the http post ?

p-himik15:05:48

Yes, exactly.

💯 4
🙏 4
kaffein15:05:13

oh ok ok thanks a lot for the tip

jeff.terrell20:05:24

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.

jeff.terrell20:05:41

Is this a known issue? Am I holding it wrong somehow?

dpsutton20:05:11

can you paste the subscription function for :data/current-user?

jeff.terrell20:05:10

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)

jeff.terrell21:05:10

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?

dpsutton21:05:20

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]

jeff.terrell21:05:33

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.

lilactown21:05:06

it’s because using a keyword as a function takes two arguments

lilactown21:05:18

(:keyword map default)

lilactown21:05:32

if map doesn’t contain :keyword, it will return the default

dpsutton21:05:33

ha nice catch

4
lilactown21:05:22

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]

4
jeff.terrell21:05:52

Ahhhh…makes perfect sense, thanks @lilactown!

lilactown21:05:40

👍 not the first time I’ve seen this 😛