Fork me on GitHub
#re-frame
<
2022-05-02
>
ns14:05:32

Hi, I'm looking for the best way to solve this problem. I use re-frame. I load data from backend and display it in a table, page 1. For each row in that table there are couple of cells that require some additional processing before displaying which is handed off to an event handler. This processing usually involves pulling substantial amount of data from firebase so it takes a while. In the meantime however, I decide to switch to page 2. Data is displayed for page 2 however shortly after it is replaced by data from page 1 because the aformentioned processing from page 1 finally finished. So I guess I need some way to cancel whatever processing might be happening on current page once the user clicks next page. That includes cancelling the http request and whatever processing is going on in event handler which updates the view again once it's finished. I see few people mentioning this article: https://github.com/day8/re-frame/blob/master/docs/Solve-the-CPU-hog-problem.md If I'm understanding it correctly, instead of looping through data inside event handler, dispatch a new event call to process each next row/chunk of data if the conditions are met (user still on the same page). That way with each call I'll have an updated copy of db in event handler which can contain a flag whether to abort or not. Another way I'm thinking is to perhaps use core.async's channels to pass information that further processing should be aborted. I'm pretty sure I'm not the only one who has dealt this problem, I'm just wondering from your experiences what's the best way to go about it. Thanks!

p-himik14:05:38

There are two ways: • Cancel everything - all the queues, all the requests, anything that's relevant. It might be harder to implement but the least amount of resources will be consumed overall, if you care about that • Assign some flag to the operations, like the relevant page ID. When an operation completes, check whether the flag is still the same - whether the stored page ID is the same as the current page ID. If it's the same - then the data is relevant. If it's not - discard the data.

ns15:05:29

Thanks, I'll check out the library. Ideally I would abort everything because it's a considerable amount of work.

carlos antonio neira bustos17:05:26

I'm trying to set the content-type of a post request but I have not being able to do it, I was using :headers { "Content-Type" "application/json"} , but does not work, also I tried :format (json-request-format)

carlos antonio neira bustos17:05:58

{ :http-xhrio {:method :post :uri "" :body (.stringify js/JSON (js-obj "driver" "ansible" , "userid" (:userid form) , "password " (:pass form))) :format (ajax/json-request-format) :mode :cors :timeout 5000 :response-format (ajax/json-response-format {:keywords? true}) :on-success [::job-run-success] :on-failure [::job-failed]}}

p-himik17:05:06

To understand why it doesn't work, check out the :body description here: https://github.com/JulianBirch/cljs-ajax#getpostput And also notice that the example that Mike has provided you with earlier uses :params.

p-himik17:05:55

Similar questions pop up once a month or something like that. A clear sign that the API of cljs-ajax could be better...

carlos antonio neira bustos17:05:28

If I use params the post request does not work

p-himik17:05:06

So... did it work in the end? :)

carlos antonio neira bustos17:05:51

I removed :body, used :params {:userid "ss"} and used :format :json

carlos antonio neira bustos17:05:45

:http-xhrio {:method :post :uri "" :params {:userid "user"} :format :json :mode :cors :timeout 5000 :response-format (ajax/json-response-format {:keywords? true}) :on-success [::job-run-success] :on-failure [::job-failed]}

p-himik17:05:38

And what was the error?

carlos antonio neira bustos18:05:10

when I use params I don't see the post request on the server, if I use body I see it

p-himik18:05:03

Do you see any errors in the JS console of your browser?

carlos antonio neira bustos18:05:09

yes, using params I see this:

carlos antonio neira bustos18:05:19

[Error] XMLHttpRequest cannot load due to access control checks. [Error] Failed to load resource: Origin is not allowed by Access-Control-Allow-Origin. Status code: 200 (exec, line 0) [Log] error is {:uri , :last-method POST, :last-error [0], :last-error-code 6, :debug-message Http response at 400 or 500 level, :status 0, :status-text Request failed., :failure :failed}

carlos antonio neira bustos18:05:50

using body I just see the response from the server

carlos antonio neira bustos18:05:26

error is {:response nil, :last-method POST, :last-error Internal Server Error [500], :failure :error, :status-text Internal Server Error, :parse-error {:status 500, :failure :parse, :response nil, :status-text JSON Parse error: Unexpected identifier "Error" Format should have been JSON keywordize, :original-text Error: Not driver available for job type: }, :status 500, :uri , :debug-message Http response at 400 or 500 level, :last-error-code 6}

carlos antonio neira bustos18:05:19

the string "Not driver available" is from the server, as I see it coming in. let me listen with netca

carlos antonio neira bustos18:05:10

using params here is the request

carlos antonio neira bustos18:05:24

OPTIONS /exec HTTP/1.1 Host: localhost:3000 Origin: Access-Control-Request-Method: POST Content-Length: 0 Access-Control-Request-Headers: content-type Connection: keep-alive Accept: */* User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15 Referer: Accept-Language: en-US,en;q=0.9 Accept-Encoding: gzip, deflate

carlos antonio neira bustos18:05:20

POST /exec HTTP/1.1 Host: localhost:3000 Content-Type: application/x-www-form-urlencoded;charset=utf-8 Origin: Accept-Encoding: gzip, deflate Connection: keep-alive Accept: application/json User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15 Referer: Content-Length: 51 Accept-Language: en-US,en;q=0.9 {"driver":"ansible","userid":"dd","password ":"ss"}

carlos antonio neira bustos18:05:36

so, I'm still in the same position where I could send the request using just :body

p-himik18:05:09

What if you replace :format :json with :format (ajax/json-request-format)? BTW, use triple backtics or the GUI button to create proper code blocks and not just inline code when you have multiple lines. It'll be much easier to read multi-line code for people that are trying to help.

carlos antonio neira bustos18:05:15

{:method         :post
                   :uri            ""
                   :params [{:userid "caaa"}]
                   :format (ajax/json-request-format)
                   :mode :cors
                   :timeout         5000
                   :response-format (ajax/json-response-format {:keywords? true})
                   :on-success    [::job-run-success]
                   :on-failure      [::job-failed]}

carlos antonio neira bustos18:05:08

that post request does not send a body, according to netcat

carlos antonio neira bustos18:05:39

OPTIONS /exec HTTP/1.1
Host: localhost:3000
Origin: 
Access-Control-Request-Method: POST
Content-Length: 0
Access-Control-Request-Headers: content-type
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15
Referer: 
Accept-Language: en-US,en;q=0.9
Accept-Encoding: gzip, deflate

p-himik18:05:49

You can also check the Network tab in the DevTools - no need for external tools. Especially helpful if you have to deal with HTTPS requests every now and again. As you can see, the request is not POST but OPTIONS - it's not supposed to have a body at all. And I'm gonna guess that you still see some CORS errors in the JS console. If so, you gotta fix those first.

p-himik19:05:52

Given that you had this error XMLHttpRequest cannot load due to access control checks. - yes.

carlos antonio neira bustos19:05:49

I thought that :mode :cors setup the headers needed for cors

p-himik19:05:33

1. You linked to the :fetch effect but you're using the :http-xhrio effect. It's a completely different thing, it has no support for :mode at all 2. :mode :cors does not make CORS errors magically go away - it just adds enough information to the requests for the browser and server to figure out whether to make or serve the request. You still have to setup CORS correctly on your server side

p-himik19:05:37

Given that :http-xhrio is supposed to work like :fetch does with :mode :cors already specified, I'm pretty sure the error is somewhere in your server configuration.

carlos antonio neira bustos19:05:28

ok, it worked now, I needed to setup CORS on the server, and use :params thanks a lot for your help

👍 1
fabrao17:05:42

hello all, what is the key event for focusout of input field? :on-focus-out?

lilactown17:05:05

i'm not sure if it's an exact corollary to focusout but there is on-blur

fabrao17:05:12

the problem with on-blur is that it happen when cursor is out and not with focus is out. If I use some auto-complete component it fails

lispers-anonymous23:05:43

I don't think there is an exact opposite of on-focus that might pick up auto-complete. MDN says the opposite of :on-focus is :on-blur https://developer.mozilla.org/en-US/docs/Web/API/Element/focus_event

fabrao23:05:31

Yes, I solved it using :on-focus in other component.

💯 1