Fork me on GitHub
#re-frame
<
2023-12-05
>
Nundrum03:12:14

I've run into a bug where POST requests to a server are sometimes failing when I use my app on my phone. In trying to debug this, I've found that I can't get re-frame-http-fx to give me both the server's response and extra data I passed in to :on-success. The docs say: > These event vectors will be dispatched (`result` is conj-ed to the end) making all encoded values AND the result available to the handlers. Which makes me think it's possible, but I'm missing something.

p-himik08:12:53

If a request fails, then it's not :on-success that is triggered.

vanelsas08:12:29

You can use on-success and on-failure and pass data. I assume you want data to be available in your on-failure method (as your request fails)? Works for POST as well.

(reg-event-fx
  :some-useful-get
  (fn [db [_ data]]
    {:http-xhrio {:method          :get
                  :uri             your-url
                  :timeout         5000
                  :response-format (ajax/json-response-format {:keywords? true})
                  :on-success      [:your-success-method data]
                  :on-failure      [:your-failure-method data]}})))

(reg-event-db
  :your-success-method
  (fn [db [_ data result]]
    ....)

(reg-event-db
  :your-failure-method
  (fn [db [_ data result]]
    ....)

p-himik08:12:56

^ just pass data into the :your-failure-method event vector as well. :)

vanelsas08:12:20

haha, oops :-)

Nundrum13:12:28

@U2FRKM4TW The problem is my on-success is being fired, which I can see because it takes the item being submitted out of the "shopping basket". And the printlns in the function also get called.

Nundrum13:12:46

So I think it's a problem with the service I'm talking to - the service is probably returning a 200 with an error code in JSON.

Nundrum13:12:21

(re-frame/reg-event-db ::upload-to-heedy-success store-basket-interceptor  
 (fn [db [x response]]                                                    
  (println "upload success " response)                                   
  (update-in db [:basket] dissoc response)                               
  ))

Nundrum13:12:03

When it is set up this way with http-xhiro: :on-success [::upload-to-heedy-success] I get a response of "{:result ok}"

p-himik13:12:44

So either it's the backend that's to blame for a wrong code, or your code for not handling the response correctly (some APIs always respond with HTTP 200 but pass the error in the body). Both cases have nothing to do with re-frame.

Nundrum13:12:45

But when I set it up this way: :on-success [::upload-to-heedy-success date] I get the date only upload success 1701745448671

Nundrum13:12:13

This does. I should be able to get my date and the response body.

p-himik13:12:21

What is store-basket-interceptor?

Nundrum13:12:35

It puts the basket map into local storage

Nundrum13:12:14

(def store-basket-interceptor             
 (re-frame/after db/basket->local-store))

Nundrum13:12:58

I know that "{:result ok}" is what the Heedy API returns on a successful upload.

p-himik13:12:08

reg-event-db without the trim-v interceptor always passes the event ID as the first item of the second argument to the event handler. That would be x in your example. When you use [::upload-to-heedy-success], response will indeed be the response. When you use [::upload-to-heedy-success date], response will always be date since you don't destructure the vector to get its third item.

Nundrum13:12:34

Eh? From the http-fx docs it reads like the date should be in the response.

Nundrum13:12:27

> These event vectors will be dispatched (`result` is conj-ed to the end) making all encoded values AND the result available to the handlers.

p-himik13:12:40

I don't see it talking about the response at all. result is probably the response, yes. But where does it say that whatever else you pass to the event vector will end up being a part of the result value? Even if it did say so, how could it possibly be true? Suppose the server answers with "hello" - how can you make an arbitrary date a part of that value?

p-himik13:12:49

The line quoted by you says explicitly: result is conj-ed to the end. So if you specify :on-success as [:evt], then on success (conj [:evt] response) will be dispatched. If you specify it as [:evt date], then (conj [:evt date] response) will be dispatched.

Nundrum13:12:35

Hmmm I kind of see. This worked:

(fn [db [_ date response]]                 
 (println "upload success " date response)

Nundrum13:12:03

Thank you 🙂 I was missing something.

vanelsas13:12:51

the code example shows this destructuring ;-)

Nundrum13:12:33

Which code example?

vanelsas13:12:09

the third message in this thread?

Nundrum13:12:29

Ah. I missed that facepalm

Ben Lieberman13:12:40

Hey, I'd appreciate a sanity check re: using the right tool for the job. I have a piece of UI that persists across route changes. Its style changes based upon data in my app-db. But I have this weird off-by-one thing happening where the UI is in the +-1 state, i.e. if the route is page 2, the UI element is in its page 1 or page 3 state. I have tried everything I know of in the re-frame toolbox, which tells me the error lies within. I have this :on-click handler:

(fn []
                          (when (<= 0 depth 4)
                            (dispatch [:update-parens-depth inc]) 
                            (dispatch [:routing/push-state route {:location @parens}])))
The parens subscription depends on the updated value of that first event, so predictably it lags behind. I tried a traditional reg-sub with and without input signals, reg-sub-raw , and a pair of effect handlers that make the appropriate changes. But @parens is always behind or ahead a step. Is there a re-frame tool (or else a library) for ensuring order in a particular fashion?

p-himik13:12:43

Don't dispatch multiple times. Instead, combine those events into one and dispatch only the new event.

👀 1
valerauko16:12:47

:fx [[:dispatch [...]] [:dispatch [...]]] fx dispatches are ordered iirc (= add an intermediate event as suggested above)