Fork me on GitHub
#clojurescript
<
2020-04-18
>
CambodianCoder04:04:57

How do you prevent checking for form validity using .checkValidity while a form/element is still rendering? I am running into an issue where react-dom logs an error to console when form.checkValidity() is called during render. I am attempting to validate fields of a form before allowing submission, via the following:

(let [form-id "create-category-form"
        ready-state #(. js/document -readyState)
        checkValidity #(when (= "complete" (ready-state))
                         (and (when (not (nil?
                                          (.getElementById js/document form-id)))
                                (.checkValidity
                                 (.getElementById js/document form-id)))))
        valid-form? #(and (.reportValidity (.getElementById js/document form-id)))]
    [:a.button.is-success
            (merge
             (when (and (checkValidity) (valid-form?))
               {:href (rfe/href :myProject.routes/categories)})
             {:on-click #(do
                           (when (valid-form?)
                             (re-frame/dispatch [:handler-with-http submit-params])))})
     "Add category"])
What is the correct way to use .checkValidity and .reportValidity without causing this error to be logged to the console?
Warning: unstable_flushDiscreteUpdates: Cannot flush updates when React is already rendering.
    in create-category-form (created by main-panel)
    in main-panel

smogg09:04:15

I could use some enlightenment. Why doesn't the promise ever resolve here?

(defonce !counter (atom 1))

(js/setTimeout #(swap! !counter inc) 1000)

(defn counter-at-n?+ [n]
  (js/Promise.
   (fn [resolve]
     (js/console.warn "counter currently at " @!counter)
     (if (= n @!counter)
       (resolve @!counter)
       (js/setTimeout #(counter-at-n?+ n) 1000)))))

(counter-at-n?+ 10)

p-himik09:04:08

Each call to counter-at-n?+ creates a new promise.

smogg09:04:04

I'm aware. But each part of the promise chain derefs the atom. Shouldn't the value be derefed one second later due to the timeout, thus making the value accurate?

smogg09:04:15

Just to be clear - the console log always returns the same value, as if the atom's value is cached for the whole promise chain. That's the part I don't understand

p-himik09:04:18

This is not a "promise chain", this is a promise within a promise without resolving anything. When the setTimeout is called from within the promise, you lose the reference to that resolve. Now you can never call it, thus never resolving that outer promise. Regarding the atom - you expect the value 10 but provide it with the value 1 that turns to 2 in a second. You never change the value of the atom, except for that second line. How do you expect 2 to become 10?

smogg09:04:29

This shhould have been an interval of course

smogg09:04:54

That's a good point about resolving, I think I get it

p-himik09:04:54

That only one problem. The memory leak with dangling promises is the other.

p-himik09:04:04

No problem.

Eamonn Sullivan10:04:06

Hi all, I have a small experimental Clojure library (https://github.com/eamonnsullivan/github-search) that I'd like to turn into a mono-repo that produces both a jar and an npm package (shadow-cljs), with some common code (.cljc). Is this possible? Has anyone tried this and can point me to an example I can study?

knubie13:04:43

Is it possible to eval js in cljs?

Roman Liutikov13:04:27

(js/eval "js string")

knubie13:04:57

ah, thanks!

potetm13:04:38

Depending on what you’re doing, js* might be more suitable.

potetm13:04:38

You did say “eval”, which implies runtime eval. But if you’re just wanting to emit raw javascript in your code, that’s what js* is for.

knubie14:04:28

@potetm Yeah I think that’s more along the lines of what I’m looking for. Do you know where I can find docs / example usage?

potetm14:04:03

(js* "alert('foo bar!')")

potetm14:04:35

just plop whatever js you want in the string

potetm14:04:19

though there are sometimes cases where you want that sort of thing, I should note that you can pretty much always accomplish it with cljs.

potetm14:04:45

e.g. the above would be (js/alert "foo bar!")

jabhi20715:04:25

Hi all, How to make Clojurescript compiler output multiple independent spec .js files for multiple specs written in clojurescript for Cypress to run test?

Frederik22:04:36

Very beginners question I'm afraid, but anyway: I made a simple clojure dummy "server-side web application" (thanks to this great idiot proof guide https://practicalli.github.io/clojure-webapps/ ) using ring and compojure. Now I'm trying to use cljs' cljs-http send a request from my front end to the server side api, without succes. I get the following:

app:cljs.user=> (go (let [response (<! (http/get ""))]
           #_=>                         (prn response)))
#object[cljs.core.async.impl.channels.ManyToManyChannel]
{:status 0, :success false, :body "", :headers {}, :trace-redirects ["" ""]
, :error-code :http-error, :error-text " [0]"}
Running curl in bash does work though (5 was the response I expected):
curl ""
5
Is there a difference between http-requests and curl I'm missing? Or am I using cljs-http incorrectly?

phronmophobic23:04:59

the requests aren’t exactly the same. what does

curl ""
respond with?

phronmophobic23:04:22

or alternatively:

(http/get "")

phronmophobic23:04:13

not sure if the trailing slash will make a difference. if that doesn’t help. I would check out the request in chrome’s network debugger

Frederik23:04:53

Thanks for the help! Unfortunately adding or deleting trailing slash doesn't make a difference. Looking at the chrome debugger gave me this though:

Access to XMLHttpRequest at '' from origin '' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
So I guess the solution lays somewhere here: https://github.com/r0man/ring-cors.

lsenjov07:04:40

It's headers. When you do a curl request, by default it doesn't add the current origin in, because it doesn't have one. When you do a request from your browser, it adds the origin in, and your webserver at localhost:8000 won't allow origin localhost:3449

lsenjov07:04:44

So either you can add something to your server that allows localhost:3449, or alternatively open up the js on the something like