re-frame

liebs 2023-12-05T13:39:40.008129Z

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-himik 2023-12-05T13:44:43.243329Z

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

👀 1
valerauko 2023-12-05T16:32:47.900409Z

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

Nundrum 2023-12-05T03:11:14.863029Z

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-himik 2023-12-05T08:52:53.727819Z

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

vanelsas 2023-12-05T08:56:29.646609Z

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-himik 2023-12-05T08:57:56.870889Z

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

vanelsas 2023-12-05T08:59:20.125899Z

haha, oops :-)

Nundrum 2023-12-05T13:36:28.033139Z

@p-himik 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.

Nundrum 2023-12-05T13:37:46.276779Z

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.

Nundrum 2023-12-05T13:39:21.467439Z

(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)                               
  ))

Nundrum 2023-12-05T13:40:03.105429Z

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

p-himik 2023-12-05T13:40:44.644489Z

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.

Nundrum 2023-12-05T13:40:45.762109Z

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

Nundrum 2023-12-05T13:41:13.312129Z

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

p-himik 2023-12-05T13:41:21.897409Z

What is store-basket-interceptor?

Nundrum 2023-12-05T13:41:35.585499Z

It puts the basket map into local storage

Nundrum 2023-12-05T13:42:14.690829Z

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

Nundrum 2023-12-05T13:42:58.904419Z

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

p-himik 2023-12-05T13:43:08.187019Z

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.

Nundrum 2023-12-05T13:47:34.439909Z

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

p-himik 2023-12-05T13:48:15.080409Z

Where?

Nundrum 2023-12-05T13:48:27.284369Z

> 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-himik 2023-12-05T13:49:40.423719Z

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-himik 2023-12-05T13:50:49.607309Z

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.

Nundrum 2023-12-05T13:52:35.194699Z

Hmmm I kind of see. This worked:

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

Nundrum 2023-12-05T13:53:03.727859Z

Thank you 🙂 I was missing something.

vanelsas 2023-12-05T13:53:51.783619Z

the code example shows this destructuring ;-)

Nundrum 2023-12-05T13:56:33.088879Z

Which code example?

vanelsas 2023-12-05T13:57:09.386239Z

the third message in this thread?

Nundrum 2023-12-05T13:59:29.920749Z

Ah. I missed that facepalm