Fork me on GitHub
#re-frame
<
2020-06-04
>
lepistane13:06:08

Hello i have question

(rf/reg-event-db
 :auth/process-response
 (fn [db [_ response]]
   (update-in db [:user :auth] #(merge % (js->clj response)))))


(rf/reg-event-db
 :auth/bad-response
 (fn [db [_ response]]
   (assoc db :error response)))


(rf/reg-fx
 :http
 (fn [{:keys [url method opts on-success on-failure parse-body]}]
   (go
     (let [http-fn (case method
                     :post http/post
                     :get http/get
                     :put http/put
                     :delete http/delete)
           res (<! (http-fn url opts))
           {:keys [status success body]} res]
       (if success
         (rf/dispatch [on-success (parse-body body)])
         (rf/dispatch [on-failure (parse-body body)]))))))


(rf/reg-event-fx
 :auth/guest
 (fn [_ [_ email old-pass new-pass]]
   {:http {:method :post
           :url ""
           :opts {:json-params {:device-id "069d1b0f4cef43abfa27cc0212c8e416"}}
           :on-success :auth/process-response
           :on-failure :auth/bad-response
           :parse-body #(js->clj (js/JSON.parse %) :keywordize-keys true)}}

           ))
when :auth/process-response happens i need to trigger one more event but i am not sure how to do it other than have
(do (rf/dispatch [:auth/process-response body])
     (rf/dispatch [:new-event (:data-i-need body)]))
but this seems not very re-framey how can i do this properly? i want to trigger new event after success is done. Should that be done in this fashion? https://github.com/day8/re-frame/blob/master/docs/Effects.md#where-effects-come-from and auth/process-response would look like ?
(rf/reg-event-fx
 :auth/process-response
 (fn [cofx [_ response]]
   {:db (update-in db [:user :auth] #(merge % (js->clj response)))
    :dispatch [:new-event (:data-i-need response)]}))

p-himik13:06:33

You almost got it. If you don't need anything but the db in the inner fn, then you can just write {db :db} instead of cofx. Right now in your code cofx is unused and db is unresolved.

πŸ‘ 4
lepistane13:06:52

so basically

(rf/reg-event-fx
 :auth/process-response
 (fn [{db :db} [_ response]]
   {:db (update-in db [:user :auth] #(merge % (js->clj response)))
    :dispatch [:new-event (:data-i-need response)]}))
?

lepistane13:06:32

thank you!

πŸ‘ 4
lepistane14:06:41

@U2FRKM4TW i've got one more if it's not a big trouble for u? this is new-event from previous code

(rf/reg-event-fx
 :ws/send
 (fn [data]
   (let [
         command {:command-id (str (random-uuid))
                  :command-type "abc}]
     (ws/send command))))
and i am sending this command using websockets my question is should this be reg-fx and then i would do
(rf/reg-event-fx
 :auth/process-response
 (fn [{db :db} [_ response]]
   {:db (update-in db [:user :auth] #(merge % (js->clj response)))
    :ws/send response}))
or is it ok to leave it like reg-event-fx?

p-himik14:06:43

Yes, it has to be an effect and not an event.

p-himik14:06:31

It's not OK to leave it like reg-event-fx. Also, apart from just employing a wrong concept, your event handler function arity is incorrect. It should be [data _] instead of just [data].

lepistane14:06:57

you mean [_ data] right?

p-himik14:06:31

Oops, right. And even then it should be [_ [_ data]]. :)

πŸ‘ 4
lepistane14:06:36

ok so the final combo is

(rf/reg-fx
 :ws/send
 (fn [data]
   (let [
         command {:command-id (str (random-uuid))
                  :command-type "abc"
                  }]
     (ws/send command))))

(rf/reg-event-fx
 :auth/process-response
 (fn [{db :db} [_ response]]
   {:db (update-in db [:user :auth] #(merge % (js->clj response)))
    :ws/send response}))

p-himik14:06:34

Seems about right.

lepistane14:06:36

thank you very much for your help πŸ™‡

aarkerio21:06:22

Hi! I just installed the "1.0.0-rc2" version and now I'm getting the message: goog.require could not find: re_frame.settings

aarkerio21:06:53

sorry, my mistake.

kenny21:06:09

How naughty is it to use app-db in a react lifecycle method? My use case is in a component-did-update handler and I'd like to check for some state in the app-db. I could simply dispatch and event and check within the event but that pollutes the event log with (potentially lots) of noise.

mikethompson22:06:44

@kenny that would be pretty bad. :-) In a view, you should use subscribe for data in app-db

mikethompson22:06:10

if you need to shuffle in values as propos for use in lifecycle methods

kenny22:06:34

Erm, this is not exactly in a view. It's kind of a weird use case stemming from a potentially poor design decision. Without going into too much detail... A component declares a EQL query to get data from the server when it loads. The decision to fetch data or not can be a complex set of rules. Thus far, the rules have been based on data available within the props of a component. Now I have a use case where those rules need to depend on something in app-db. An option is to keep this particular piece of state in a separate atom itself. I don't like that solution since I tend to want to keep all related data together.

lilactown22:06:32

I think mike is suggesting to pass it in as props instead of using the app-db in the lifecycle method

lilactown22:06:01

then the component that renders the component that’s fetching can subscribe and pass it in

kenny23:06:58

Ohhh. Hmm, that is possible. Will consider. Thanks both πŸ™‚