Fork me on GitHub
#re-frame
<
2020-04-27
>
jeff.terrell16:04:27

I'm seeing some odd behavior in my re-frame app that I don't understand. I have an event with both an :http-xhrio effect a :db effect. The effect sends an XHR to my backend and gets a response, but the browser tab hangs (with my CPU pegged) before either the success or failure event fires.

jeff.terrell16:04:46

On Chrome, the XHR is marked as "pending" in the dev tools network panel even though I can view the response headers. The backend logs indicate it finished sending the response.

jeff.terrell16:04:06

On Firefox, I get a "this script is taking a long time, do you want to kill it?" message.

dominicm16:04:17

XHR requests can be synchronous

jeff.terrell16:04:21

Oddly, if I comment out the :db effect, everything works fine.

jeff.terrell16:04:21

Here's the code I'm using, in case there's something obvious I'm missing:

(rf/reg-event-fx ::create-student
  (fn [cofx [form-data]]
    {:http-xhrio {:method :post
                  :uri (api-url "/student")
                  :body form-data
                  :format :multipart
                  :response-format (ajax/text-response-format)
                  :on-success [:create-student-success form-data]
                  :on-failure [:create-student-failure]}
     ;; :db (assoc-in (:db cofx) [:xhr :create-student] {:in-flight? true})
     }))

jeff.terrell16:04:03

(`form-data` is a JS FormData object provided from the form submit event.)

jeff.terrell16:04:10

@dominicm - I'm not sure what the implications of a synchronous XHR would be. Could that explain the behavior I'm seeing here? And is there a way to disable synchronous XHRs from the :http-xhrio effect?

jeff.terrell16:04:41

It looks like cljs-ajax only does async XHRs, so maybe synchronous XHRs aren't anything I need to worry about: > All requests are asynchronous, accepting callback functions for response and error handling. https://github.com/JulianBirch/cljs-ajax

jeff.terrell16:04:04

Anyway, anybody have any ideas about what could cause this? It seems to be an infinite loop between my :http-xhrio effect and the success/failure events, but only if there's a :db effect in my effect map. Very odd!

joelsanchez16:04:39

install re-frame-10x and inspect what event handlers get dispatched

joelsanchez16:04:50

else just js/console.log your handlers to figure it out

joelsanchez16:04:56

I see nothing wrong with your handler but I can't see the rest of the code, which is probably at fault

jeff.terrell16:04:56

Well, I already have prn statements at the top of my success/failure handlers, and they're not printing anything when my :db effect is present. Do you think I should use re-frame-10x or js/console.log instead?

joelsanchez16:04:32

well I mean, if you have binaryage/cljs-devtools installed (which you should have), js/console.log allows you to inspect cljs values in the console

joelsanchez16:04:08

re-frame-10x would allow you to see what are your handlers doing and what handlers are being dispatched and with what params, quite handy

joelsanchez16:04:38

it's quite absurd to think that your db effect is doing anything wrong - however you could try to do just that, return the db effect but not the http-xhrio

joelsanchez16:04:05

if it still hangs, assume you're: • using reg-event-db where you should use reg-event-fx or viceversa

joelsanchez16:04:14

• somehow overwriting the dbeffect accidentally

joelsanchez16:04:07

perhaps a subscription or a view is causing the infinite loop, try changing something else within the db and see if that helps, variations of that will help you get to the problem

joelsanchez16:04:33

tbh now that I think about it I'd bet on a sub or view causing the problem. good luck

jeff.terrell16:04:42

Some very useful tips, thanks! The last thing in particular sounds like a hypothesis that fits all the facts. I bet that's my issue, somehow. Thanks!

superstructor21:04:05

Hi @U056QFNM5 how did your debugging go ?

superstructor21:04:41

Btw there is also https://github.com/superstructor/re-frame-fetch-fx if your interested in a http-fx alternative 😉

superstructor21:04:07

But I doubt that http-fx itself is the issue.

superstructor21:04:44

If you do find anything at fault in re-frame or http-fx I'd be very interested to hear about it so we can fix it 🙂 @U056QFNM5

jeff.terrell14:04:34

Thanks @U0G75S29H! I haven't had a chance to dig in yet—it's mainly a weekend project—but I will try to report back after I do.

jeff.terrell14:04:21

Your library looks interesting. Thanks for mentioning that. In terms of underlying abstractions, I definitely understand native fetch a lot better than the Google library AJAX stuff, so I'm inclined to give it a shot.

jeff.terrell13:05:27

Confirmed: that was the issue! I had a component named xhr-status, which I was intending to use, but I forgot that I had introduced a new xhr-status name via the enclosing let block. Its value was @(rf/subscribe ,,,). I'm not clear on the details of why this caused an infinite loop while rendering, but it did. Thanks again for the help, @U5LPUJ7AP! /cc @U0G75S29H

👍 4
Lu16:04:43

Look around the component where you dereference the subscription that uses the :in-flight? value .. pretty sure the infinite loop happens there

jeff.terrell17:04:00

That's gotta be it! I can't look now, but I'm almost sure that's it. It explains everything I'm seeeng. Thanks!

🙂 4