clojurescript

ClojureScript, a dialect of Clojure that compiles to JavaScript http://clojurescript.org | Currently at 1.10.879
tskardal 2020-11-22T09:06:44.352400Z

How would you go about making a reusable component/widget (with state!) in cljs that can be instantiated multiple times from js? How can I make each instance have its own atom?

p-himik 2020-11-22T09:22:57.352500Z

Just create a closure.

(defn init-comp [stuff]
  (let [state (atom stuff)]
    (fn [other-stuff]
      (println "New stuff:" (reset! state other-stuff)))))

p-himik 2020-11-22T09:23:14.352700Z

It's absolutely the same as you'd do in JS.

tskardal 2020-11-22T09:33:08.352900Z

Got it! Thanks 🙂

tskardal 2020-11-22T09:49:57.355400Z

Another beginner question: when calling my cljs code (in ns counter.core) from js, I get the error ReferenceError: counter is not defined. I tried placing the code in an event handler for DOMContentLoaded, but with the same result. If I make the same call from the developer console it works. When is the cljs code ready to use?

p-himik 2020-11-24T14:38:16.390600Z

Just place the JS code right after the <script> that loads the CLJS bundle.

tskardal 2020-11-24T18:37:20.402700Z

That’s what I did :man-shrugging:

tskardal 2020-11-24T18:40:45.402900Z

<!DOCTYPE html>
&lt;html&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="c1"&gt;&lt;/div&gt;
&lt;div id="c2"&gt;&lt;/div&gt;
&lt;div id="c3"&gt;&lt;/div&gt;
&lt;script src="out/main.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
    function ready(callbackFunction){
      if(document.readyState != 'loading')
        callbackFunction(event)
      else
        document.addEventListener("DOMContentLoaded", callbackFunction)
    }
    ready(event =&gt; {
      console.log('DOM is ready.')
      // nope
      //counter.core.run(document.getElementById("c3"));
    })
    // also nope
    counter.core.run(document.getElementById("c3"));
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

p-himik 2020-11-24T18:42:14.403100Z

Are you exporting the counter.core/run function?

tskardal 2020-11-24T18:42:47.403300Z

Yes

p-himik 2020-11-24T18:43:38.403500Z

No idea - the exact same patter has worked for me multiple times, unless I'm missing something. Can you create a minimal reproducible example on GitHub?

tskardal 2020-11-24T18:43:40.403700Z

if I compile it like this it works:

clj -m cljs.main --optimizations advanced -c counters.core

tskardal 2020-11-24T18:45:46.403900Z

if I compile it like this, it doesn’t:

clj --main cljs.main --compile counters.core --repl

p-himik 2020-11-24T18:48:21.404100Z

What if you just drop the --repl part and leave the rest of the arguments?

tskardal 2020-11-24T18:52:11.404300Z

nope

tskardal 2020-11-24T18:52:24.404500Z

I pushed it to a github repo https://github.com/tskardal/cljs-counters

p-himik 2020-11-24T18:56:03.404800Z

Hold on, there's no counters namespace in that code.

tskardal 2020-11-24T18:57:04.405Z

ah 😅 you are right, but that’s kind of expected 😛 I’ve renamed the package when pasting code here

tskardal 2020-11-24T18:57:23.405200Z

in the repo it is clickbait.core

p-himik 2020-11-24T19:03:45.406500Z

In a clean copy of your repo, my steps were: - Run clj --main cljs.main --compile clickbait.core - Edit index.html so it only has the clickbait.core.run(document.getElementById("c3")); line in the last &lt;script&gt; tag Works perfectly, as far as I can tell.

tskardal 2020-11-24T19:04:26.407Z

if you get three counters, yes

p-himik 2020-11-24T19:05:32.407200Z

Ah, hold on.

p-himik 2020-11-24T19:07:08.407400Z

Ahh, right, I see. The development bundle uses document.write that writes &lt;script&gt; tags after the relevant line with clickbait.core.run.

p-himik 2020-11-24T19:13:06.407600Z

OK, I think now I have the full picture. You cannot really add stuff to index.html. You have to add it to one of the CLJS files. Alternatively, use a more advanced build tool than the vanilla cljs.main. Shadow-cljs has an :init-fn build parameter for that.

tskardal 2020-11-24T20:10:54.409100Z

Ah, I see. Thanks for clarifying 🙂

tskardal 2020-11-22T14:21:12.355700Z

When building a "production build" it works fine. Why is that?

Milan Munzar 2020-11-22T19:53:41.359700Z

Hey, I have done some https://github.com/mimunzar/CommandLine/tree/master/scripts for cljs compiler and test outputs which you might find useful when developing on Node. There is also a script which generates Cljs project and makefile.