Fork me on GitHub

Hello all, very new to clj and cljs. have been trying to get a good cljs environment set up in vscode using calva, but cant seem to connect to a repl. I want to be able to create small scripts using cljs, so want to target node and be able to use npm packages. I have figured out how to interact with npm packages and how to compile the code, but cant seem to get a good environment set up


maybe also try #vscode


shadow-cljs and Calva are friends. Of that's not an option I think Clover might work.


if anyone has went through this process before and can help, all the help is much appreciated

Chris McCormick12:11:06

does anybody have any tips for memoizing the result of a function that wraps a core.async go block in clojurescript?


go returns a channel, so why don't you extract whatever you're doing inside the go block into its own function, and memoize that function instead?

Chris McCormick12:11:07

one of the functions is a low level js call which returns a promise and i can't seem to get promises with <p! to memoize.

Chris McCormick12:11:44

i set up a small experiment like this:

(defonce mem-p (fn p [x]
                 (js/Promise. (fn [res rej]
                                (js/setTimeout #(res x) 1000)))))

  (print "starting")
  (print (<p! (mem-p "x"))))
however it always takes one second to return

Gleb Posobin13:11:56

defonce does not memoize the function, it just prevents defining it again when it is already defined when you reload the namespace.

Gleb Posobin13:11:38

Here you need custom memoization, something like:

(def cache (atom {}))

(defn mem-p [x]
  (if (contains? @cache x)
    (js/Promise.resolve (@cache x))
    (-> (p x)
          (fn [val]
            (swap! cache assoc x val)

Chris McCormick13:11:36

> defonce does not memoize the function wow, somehow i forgot to actually wrap that in memoize facepalm

Chris McCormick13:11:13

when i wrap the fn in memoize is starts be behave as expected:

(defonce mem-p (memoize (fn p [x]
                          (js/Promise. (fn [res rej]
                                         (js/setTimeout #(res x) 1000))))))
sorry for the noise!

Gleb Posobin14:11:43

Hmm, this will store the resolved promise, didn't expect this to work, but makes sense.


Hello, does anyone have any experience with trying to write Office addins using the in Clojurescript?

Chris McCormick13:11:08

i used wisp to write an office add-in so i may be able to help depending on what the issue is (wisp is not clojurescript but is clojure-like and shares some similarities)

Chris McCormick13:11:53

the office api makes heavy use of promises so i imagine the new <p! from core.async would come in very handy


does anybody understand how the following deftest (defined in a .clj file) is being run in this example project? the readme is woefully incomplete on this aspect of it.


I tried following this setup and my cljs test environment (w/ figwheel main & tools.deps) just ignores that file/test


@johanatan my guess would be lein test?


@thheller yep, that’s my guess as well. But does this run both the cljs tests and the clj one?


In my case I already have a bunch of deftests that are running in the CLJS context


looks like CLJ is driving the CLJS tests in this case?


I mean isn't that was the library is about?


Not entirely no. This library does what it does. It doesn’t “drive” all of your “CLJS tests”


@thheller that drives the devcards tests yes


The question is about how to integrate that into an existing CLJS test infrastructure


I might be missing the point of the library but it looks to me like that IS the test infrastructure. you define devcards, it takes screenshots and compares results.


That is one aspect of a testing infrastructure


It is not the totality

Andrei Stan19:11:43

hi, i`m trying to set-up react-dropzone, but without success; can someone point me in the right direction with this one ? :

import React from 'react'
import Dropzone from 'react-dropzone'

<Dropzone onDrop={acceptedFiles => console.log(acceptedFiles)}>
  {({getRootProps, getInputProps}) => (
      <div {...getRootProps()}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
my code in clojurescript:
(defn MyDropzone [] (let [onDrop (react/useCallback (fn [acceptedFiles] (js/console.log acceptedFiles))) props (useDropzone (clj->js {"onDrop" onDrop})) get-root-props (.-getRootProps props) get-input-props (.-getInputProps props)] [:> react/Dropzone [get-root-props get-input-props] {:on-drop #(js/console.log (-> %))} [:section [:div (get-root-props) [:input (get-input-props)] [:p "Drag n' drop some files here"]]]]))
main.js:1673 Invariant Violation: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See  for tips about how to debug and fix this problem.
    at invariant ()
    at Object.throwInvalidHookError ()
    at Object.useCallback ()
    at cmp.netdava$homebank$app$converter$MyDropzone [as reagentRender] ()
    at eval ()
    at Object.reagent$impl$component$wrap_render [as wrap_render] ()
    at Object.reagent$impl$component$do_render [as do_render] ()
    at eval ()
    at Object.reagent$ratom$in_context [as in_context] ()
    at Object.reagent$ratom$deref_capture [as deref_capture] ()


react/Dropzone doesn't look like react-dropzone/Dropzone. By default, Reagent generates class components. More details on how to overcome this are here and in the next section:


“run-tests-async” runs CLJS tests


@johanatan I don't have a clue. you asked how the deftest would be run and it looks like lein test. I don't know anything about the rest.


I suppose the test.cljs.edn and figwheel come into play somehow


Yes I asked that because the normal way this works is for the one I linked to run. Therefore there is a question about what mechanism precisely allows both varieties of these tests to work. Particularly the “abnormal” one.


It is a valid question whether you see it or accept it or not.


If you “don’t know anything about the rest” then perhaps waiting for someone who does to chime in would be a good tack?


ok, goodbye. sorry I tried answering your initial question.


No worries. I appreciate the attempt

Karol Wójcik20:11:56

That was rude!

👍 18

i've found the answer: I need a separate (pure Clojure) "main" and to manually call "clojure.test/run-all-tests" (which leiningen is automagically doing).