Fork me on GitHub
#clojurescript
<
2021-12-27
>
brendnz03:12:00

I have two questions, but only one here (companion question is on #calva channel). When I run clj -M --main cljs.main , Clojure on the JVM creates a repl in a firefox browser instance, but does not present a repl prompt at the terminal. I mention this only to show the minimum necessary to get a browser repl loaded whether or not accessible. Let's say I add sufficient options to get a repl prompt at the terminal and I can enter and evaluate forms from this prompt. When I send say (+ 1 1) from the repl prompt, does it go to the JVM repl first and then get passed to the browser repl, or does it go direct to the browser repl?

Kevin Depue03:12:05

Hey folks, I’m trying to run through figwheel’s tutorial and get the following error when launching the lein app:

Kevin Depue03:12:27

...
Retrieving rewrite-cljs/rewrite-cljs/0.4.3/rewrite-cljs-0.4.3.jar from clojars
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See  for further details.
Syntax error compiling at (figwheel/main/logging.clj:170:14).
No such var: figwheel.core/inline-message-display-data

mal06:12:51

Someone else had this as well… but no reply. There are #figwheel-main and #figwheel channels… https://clojurians.slack.com/archives/CALJ3BFLP/p1603900336093300 I ran through https://figwheel.org/tutorial.html it and it worked without that syntax error on my mac.

Gerome06:12:35

Could you provide a git repo for us to reproduce the issue?

Gerome06:12:28

In fact, could you take the time and setup a new repo from scratch to see if the error persists? That's at least how I would approach this.

Kevin Depue11:12:15

@UPJP9G4G1 Actually this is literally just the following:

Kevin Depue11:12:30

lein new app test

Kevin Depue11:12:41

Then copying the project.clj from the figwheel website verbatim:

Kevin Depue11:12:25

(defproject example-project "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.9.0"]]
  :profiles 
    {:dev 
      {:dependencies [[org.clojure/clojurescript "1.10.773"]
                      [com.bhauman/figwheel-main "0.2.15"]
                      ;; optional but recommended
                      [com.bhauman/rebel-readline-cljs "0.1.4"]]}})

Kevin Depue11:12:23

lein trampoline run -m figwheel.main

Kevin Depue11:12:41

Dependencies are downloaded as normal and then boom:

Kevin Depue12:12:45

There's a gist of the output for me

Kevin Depue12:12:56

This happens on both Ubuntu and OSX for me

lilactown21:12:08

worked for me

Kevin Depue22:12:38

what version of java are you on?

Kevin Depue22:12:04

[kevin@linux ~/repos/figwheel]
$ java -version
openjdk version "11.0.11" 2021-04-20
OpenJDK Runtime Environment (build 11.0.11+9-Ubuntu-0ubuntu2.20.04)
OpenJDK 64-Bit Server VM (build 11.0.11+9-Ubuntu-0ubuntu2.20.04, mixed mode, sharing)

lilactown22:12:32

openjdk version "17.0.1" 2021-10-19
OpenJDK Runtime Environment Homebrew (build 17.0.1+1)
OpenJDK 64-Bit Server VM Homebrew (build 17.0.1+1, mixed mode, sharing)
using an M1 macOS machine

Kevin Depue23:12:27

Ok so, it appears it broke because I called my lein app figwheel

Kevin Depue23:12:41

Created a new app called figwheel-test and it worked :face_with_rolling_eyes:

lilactown23:12:07

ah your source files were overriding fig wheels

ChillPillzKillzBillz08:12:21

I added the following in my deps.edn and it seems to work...

org.slf4j/slf4j-simple {:mvn/version "1.7.32"}
        org.slf4j/slf4j-api {:mvn/version "1.7.32"}
Best of luck...

Kevin Depue03:12:35

Just curious how to work around this

Sam Ritchie12:12:08

hey all, strange error here with a node REPL… I have a data reader installed with the pair sicm/quaternion sicmutils.quaternion/parse-quaternion . When I use it with #sicm/quaternion [1 2 3 4] in Clojure no problem. in cljs, however, I see

sicmutils.complex> #sicm/quaternion [1 2 3 4]
Execution error (IllegalStateException) at clojure.tools.reader/read-tagged (reader.clj:855).
Attempting to call unbound fn: #'sicmutils.quaternion/parse-quaternion
even though the function is indeed bound:
sicmutils.complex> (sicmutils.quaternion/parse-quaternion [1 2 3 4])
(sicmutils.quaternion/make 1 2 3 4)

Sam Ritchie12:12:39

other data readers are working fine

Sam Ritchie12:12:20

something bigger and prject-specific must be weird, I will attack this from a few angles

Sam Ritchie12:12:01

very weird, I HAD required the sicmutils.quaternion namespace where I was getting that error. but adding a require for it to a different namespace fixed the issue

zendevil.eth14:12:50

how to convert an char to a number in cljs?

zendevil.eth14:12:55

(int \a) doesn’t seem to work?

p-himik14:12:43

When in doubt, just look up how to do it in JS and then use interop.

zendevil.eth14:12:45

Both (js/parseInt \a) and (js/parseInt “a”) give NaN

p-himik15:12:48

Because it's not an int?

p-himik15:12:05

Look up "js get char int code" or something like that.

p-himik15:12:34

Also, in CLJS \a is exactly identical to "a" - there's no difference whatsoever.

☝️ 1
zendevil.eth15:12:45

I’m trying to hash the users’ password and send that to the db like so:

(hash "kasjfl")
Is this the recommended way to hash passwords?

p-himik15:12:54

Read the output of (doc hash) and notice how it says "hash code". A hash code is not the same as a cryptographic hash/checksum that you need for password checking (assuming that's what the intended usage is).

p-himik15:12:33

In CLJ, one of the common libraries to use for that is https://github.com/funcool/buddy No clue whether something like that exists for CLJS but you can certainly find an NPM library for that or maybe use built-in JS API if there's support for cryptographic stuff.

zendevil.eth17:12:18

I have a component like so:

[:> flabel/FloatLabel
           {:label "Title"
            :name "title"
            :value @title}
           [:> a/Form.Item
            {:name "title"}
            [:> a/Input
             {:onChange #(reset! title (.-value (.-target %)))
              :size "large"}]]]
FloatLabel is actually created in react:
export const FloatLabel = props => {
    const [focus, setFocus] = useState(false);
    const { children, label, value } = props;
    var floatClass, focusClass, labelClass;

    labelClass = "float-label";

    focusClass = focus ? ` ${labelClass}--focused` : "";
    floatClass = value ? ` ${labelClass}--floated` : "";

    labelClass = labelClass.concat(focusClass, floatClass);
    
    return (
        <div
            className="float-label-wrapper"
            onBlur={() => setFocus(false)}
            onFocus={() => setFocus(true)}
        >
            {children}
            <label className={labelClass}>{label}</label>
        </div>
    );
};
but when I input something in the input, I see the cursor flickering, suggesting that the whole component is rerendering when I reset the value. Is there a way to fix this flickering?

p-himik17:12:39

Would be more appropriate for #reagent

Asko Nōmm20:12:34

Hi! I have two concecutive (set!) calls, but I don’t think they happen syncronously, is there a way to do that? Example:

(set! (.-height (.-style el)) 0)
(set! (.-height (.-style el)) 400)
In this case, only the 0 ever gets set.

Asko Nōmm20:12:56

In JS, the equivalent would be

el.style.height = 0:
el.style.height = 400;
And it would be synchronous, so 400 would be the value that gets set. But in CLJS apparently that’s not the case 😞

lilactown20:12:30

what makes you believe it isn't synchronous?

Asko Nōmm20:12:43

Because I inspect the DOM, and 0 is the value set.

lilactown20:12:08

here's an example I typed into http://app.klipse.tech

(def el #js {:style #js {:height nil}})

(set! (.-height (.-style el)) 0)
(set! (.-height (.-style el)) 400)
and the resulting JS:
cljs.user.el = ({"style": ({"height": null})});
cljs.user.el.style.height = (0);
cljs.user.el.style.height = (400);

lilactown20:12:22

there's nothing async happening here. it complies to essentially what you want the JS equivalent to be

lilactown20:12:47

so I would look for something else that might be causing your element's height to be 0

Asko Nōmm20:12:11

I am setting it to 0. Right before I set it to something else.

Asko Nōmm20:12:30

Just like in the example I gave, and yet the second call has no effect. (Reagent).

lilactown20:12:56

it sounds like there something else going on with your code than calling set! twice in a row

lilactown20:12:12

perhaps it's where / when you are calling set!

Asko Nōmm20:12:30

:component-did-update
      (fn []
        (set! (.-height (.-style @ref*)) 0)
        (set! (.-height (.-style @ref*)) (.-scrollHeight @ref*))
Essentially when a component updates, I set the height of a textarea to 0, and then to its scrollHeight (so that when text was deleted, the height would decrease, because otherwise scroll height remains large).

Asko Nōmm20:12:39

Very basic thing to do in regular JS, but can’t seem to make it work in CLJS 😞

lilactown20:12:05

have you ensured that the scrollHeight is not 0 when your component updates?

Asko Nōmm20:12:03

Yup, if I print before the sets the scrollHeight, its 40

Asko Nōmm20:12:21

Then its being set to 0, but then never back to scrollheight.

lilactown20:12:27

:component-did-update
      (fn []
        (set! (.-height (.-style @ref*)) 0)
        (set! (.-height (.-style @ref*)) (doto (.-scrollHeight @ref*) (prn))))
☝️:skin-tone-2: this prints 40?

Asko Nōmm20:12:59

No, print before the sets. Right before the first set!

lilactown20:12:14

you're reading the scrollHeight after setting the height to 0

lilactown20:12:32

the code you pasted is equivalent to:

ref.current.style.height = 0;
ref.current.style.height = ref.current.scrollHeight;

Asko Nōmm20:12:13

Yup!, that causes repaint of the textarea, which is what I want

lilactown20:12:17

so I'm checking to see what the scrollHeight is after you set the height to 0, since that's what you're setting the height the second time

Asko Nōmm20:12:12

So Im growing the textarea automatically as you type text in the textarea right, but when you delete text, the scrollHeight doesnt go smaller, stays the same. So a way to trick it into “reflowing”, is to cause a re-paint, and so do that by setting the height to 0, then that re-calculated scrollheight, and then set the height to scrollheight.

lilactown20:12:53

I think I understand that. but what does my CLJS example print?

Asko Nōmm20:12:37

Prints correct scrollHeight. First line of text is 64 for example, as it goes to second line it becomes 88, and so on, and so on.

Asko Nōmm20:12:47

But it doesnt actually change the height of the texarea tho, textarea is still 0.

lilactown20:12:02

I can reproduce this using React + JS

lilactown20:12:11

dunno why it behaves that way but it doesn't seem to have to do with clojurescript

Asko Nōmm20:12:04

Ah damn, you’re right, thanks for the help tho’! Much appreciated.

lilactown20:12:40

ahaha, I think I know. it's a bit tricky

lilactown20:12:16

I googled for "react textarea set height to scrollheight" and found this gist https://gist.github.com/sikanhe/015c606710dc656f0c40

lilactown20:12:32

the key lines are

const textarea = this.refs.textarea
    textarea.style.height = textarea.scrollHeight + 'px'

lilactown20:12:42

notice that they add 'px' to the end

lilactown20:12:48

I think if you try

:component-did-update
      (fn []
        (set! (.-height (.-style @ref*)) 0)
        (set! (.-height (.-style @ref*)) (str (.-scrollHeight @ref*) "px")))
it will work

Asko Nōmm20:12:04

Omgggg it did it!!!

Asko Nōmm20:12:22

I was so use to Reagent just adding pixels itself under the hood that I didnt even think about that

Asko Nōmm20:12:39

Because when I directly overwrite JS object value Reagent wont do anything there

lilactown20:12:10

yeah React adds the px to styles passed in to elements, but as you say here we are going around both React and Reagent

Kevin Depue21:12:40

Hey folks, curious if anyone saw my thread above, I still can't get figwheel to work :(

1
seancorfield22:12:07

It works just fine for me -- I see the following after the downloads:

[Figwheel:WARNING] Attempting to dynamically add "target" to classpath!
[Figwheel:WARNING] Target directory "target" is not on the classpath
[Figwheel:WARNING] Please fix this by adding "target" to your classpath
 I.E.
 For Clojure CLI Tools in your deps.edn file:
    ensure "target" is in your :paths key

 For Leiningen in your project.clj:
   add it to the :resource-paths key
[Figwheel] Compiling build figwheel-default-repl-build to "target/public/cljs-out/figwheel-default-repl-build-main.js"
[Figwheel] Successfully compiled build figwheel-default-repl-build to "target/public/cljs-out/figwheel-default-repl-build-main.js" in 12.285 seconds.
[Figwheel] Starting Server at 
[Figwheel] Starting REPL
Prompt will show when REPL connects to evaluation environment (i.e. a REPL hosting webpage)
Figwheel Main Controls:
          (figwheel.main/stop-builds id ...)  ;; stops Figwheel autobuilder for ids
          (figwheel.main/start-builds id ...) ;; starts autobuilder focused on ids
          (figwheel.main/reset)               ;; stops, cleans, reloads config, and starts autobuilder
          (figwheel.main/build-once id ...)   ;; builds source one time
          (figwheel.main/clean id ...)        ;; deletes compiled cljs target files
          (figwheel.main/status)              ;; displays current state of system
Figwheel REPL Controls:
          (figwheel.repl/conns)               ;; displays the current connections
          (figwheel.repl/focus session-name)  ;; choose which session name to focus on
In the cljs.user ns, controls can be called without ns ie. (conns) instead of (figwheel.repl/conns)
    Docs: (doc function-name-here)
    Exit: :cljs/quit
 Results: Stored in vars *1, *2, *3, *e holds last exception object
[Rebel readline] Type :repl/help for online help info
Opening URL 
ClojureScript 1.10.773
cljs.user=> 
That's on macOS. And my browser opens just fine. What is in your ~/.lein/profiles.clj file? That's the biggest source of lein-related bugs.

Kevin Depue22:12:09

I don't seem to have that file

1
Kevin Depue22:12:33

The part that breaks is lein trampoline run -m figwheel.main

Kevin Depue23:12:27

Ok, so it appears that it didn't work because I called my lein app figwheel

Kevin Depue23:12:58

Created a new app called figwheel-test and it works :face_with_rolling_eyes:

1