Does anyone know of a ClojureScript playground equivalent of CodePen/CodeSandbox?
I do not, but i imagine you could spin one up rather quickly with figwheel?
I'd like to be able to easily share frontend code and its visual effect with others via a URL...
theres this: http://app.klipse.tech/
@dpsutton That's quite nice for embedding live code into a website. But are there are no CLJS solutions for quickly creating a small code sandbox with dependencies (eg. reagent), and sharing it via URL?
not that i'm aware.
OK, thanks.
Hello there! Please help. How do I set up HTML5 history with retit
in my webapp on shadow-clj?
I used the official example https://github.com/metosin/reitit/tree/master/examples/frontend
Except for having shadow-clj instead of figwheel. And basically copy-pasting server and frontend code with the following addition on config:
:dev-http {8000
{:root "public"
:handler shadow.server/handler}}
And It show the weird error on any path except /
.
Uncaught SyntaxError: expected expression, got '<' web-api.js:1
If there are anyone who set up retit with html5 history in cljs, please answer!
@altjsus that means your server served some HTML when it was expecting some Javascript
maybe your handler didn't properly serve the files
For form2 componet in reagent: https://github.com/reagent-project/reagent/blob/master/doc/CreatingReagentComponents.md#form-2--a-function-returning-a-function
What args will be passed in to the inner function?
(defn timer-component []
(let [seconds-elapsed (reagent/atom 0)] ;; setup, and local state
(fn [a b c d e f g h i j k ] ;; inner, render function is returned
(js/setTimeout #(swap! seconds-elapsed inc) 1000)
[:div "Seconds Elapsed: " @seconds-elapsed])))
If I add arbitrary args, e.g., a, b, c, d, e,f⦠nothing goes wrong. The function arity is fine. Weird.the same args as the outer fn
just might change on update, the outer ones you only get once
In any case the outer args would change?
[out-func arg1 arg2] They are fixed written in the code.
Fundamentally, when reagent calls the inner func, where are the args from?
as I said ... they are the same args. don't have time to explain this further sorry.
all this does is let you create state once on mount, after that is only calls the inner function
I saw this: https://cljdoc.org/d/reagent/reagent/1.0.0/doc/tutorials/when-do-components-update-#1-props which answers my question.
Hi everyone π what is the correct way to handle uuid deserialisation from transit in cljs? the default is to com.cognitect.transit
UUID instead of cljs.core/UUID, Thanks π
is it still: just add (extend-type com.cognitect.transit.types/UUID IUUID)
to your code, as per: https://github.com/cognitect/transit-cljs/issues/41?
yeah go ahead and do that. that's the most confusing bug ever ha
yeah it was pretty surprising to see
thanks!
Do you guys know of any beginner-friendly and free tutorials for ClojureScript // ClojureScript Reagent?
I found https://www.braveclojure.com/ was helpful
And then the reagent docs, once you have a grasp on the clj/cljs syntax
Is there a simple way to escape core async using callbacks?
there are take! and put! fns using callbacks I guess, but why use callbacks? XD https://clojure.github.io/core.async/#clojure.core.async/take!
How would I rewrite this
(defn async-plus []
(go (<! (go (+ 1 1)))))
So when I call it I get the result and not the channel.cljs or clj?
cljs
so you want make it a sync call?
I want to escape channels
I think take!
is your only option there
you've got extra levels of go
and <!
there just pointing out. And you cannot. Imagine (+ 1 1)
took three seconds. There is no notion of blocking or waiting in js like that
In cljs you cant make it sync, since you are async you will always be async. In clojure you could wait for the result blocking the current thread, on cljs you cant cause its single threaded js
Iβve got it there for simplicity. Assuming that the (+ 1 1) is an operation that must be async. The <! is to simulate me taking from it. Which also must itself be in a go block.
(go (<! (go (+ 1 1))))
would be equivalent to (go (+ 1 1))
they both will be a channel with the value 2
on it
Yea I just thought that between the first go and take. When the value is received. There would be a way to use a callback or something to return it. But I canβt figure it out.
(take! (go (+ 1 1)) your-callback-fn)
or
(go (your-callback-fn (<! (go (+ 1 1))))
(defn async-plus []
(take! (go (+ 1 1)) identity))
returns nil
when calledfrom the docs:
Usage: (take! port fn1)
(take! port fn1 on-caller?)
Asynchronously takes a val from port, passing to fn1. Will pass nil
if closed. If on-caller? (default true) is true, and value is
immediately available, will call fn1 on calling thread.
fn1 may be run in a fixed-size dispatch thread pool and should not
perform blocking IO, including core.async blocking ops (those that
end in !!).
Returns nil.
Iβm obviously stuck. Seems there is no solution?
no. you can't wait for an async operation to continue and carry on like that. the callback has to be the thing to handle it
in clojure you could do (println (<!! (go (+ 1 1))))
in CLJS you cant
So I probably have to introduce an atom here and try and figure out some trickery
imagine (take! (go (+ 1 1)) identity)
the (+ 1 1)
takes 20 seconds. javascript has no way to pause the world while waiting for the twenty seconds
I know. I just thought there might be a simple callback solution.
it's just going to call (identity 2)
in twenty seconds
all good. I think I have to rethink how I want to approach this
Question about self-hosting cljs. Is there a way to use the compiler option :warning-handlers
with cljs.js/eval-str
?
It looks like the available options of [cjs.js/eval-str](https://cljs.github.io/api/cljs.js/eval-str) are limited.
(defn evaluate [s callback]
(cljs.js/eval-str
compile-eval-state
s
nil
{:eval cljs.js/js-eval
:load (partial shadow.bootstrap/load (analyzer/empty-state))
:warning-handlers [my-fn]
:context :expr}
(fn [result] (do (js/console.log result)
(callback result)))))
I also tried to pass compiler-options as an argument of analyzer/empty-state
but I had no success.anyone else is having problems with Calva
in VS-Code and clojure-lsp
never managing to start?
it seems something fixed itβ¦ no idea what π will do if I encounter it again.
Deal! π
Hello im starting to dig into promise chaining in cljs, and for the moment I'm happy with core.async
.
(https://clojurescript.org/guides/promise-interop#using-promises-with-core-async)
But I don't know how to compose π Is it an easy way to get back a js/promise from a channel?
I'm thinking on wrapping chan in a js/promise
and using take!
to trigger the callback. Is there a better way to do?
i think it would be something like this:
(def c->p [c]
(let [p (js/Promise.)]
(take! c #(.resolve p %))
p))
oh and return p sorry
thx I will add a bit of error handling and it will be nice π
if you check the source of the macro p->c it will be largely like this
ah its <p!
.
ah yes, it does the error checking :thumbsup:
cljs.user=> (source clojure.core.async.interop/p->c)
(defn p->c
"EXPERIMENTAL: Puts the promise resolution into a promise-chan and returns it.
The value of a rejected promise will be wrapped in a instance of
ExceptionInfo, acessible via ex-cause."
[p]
(let [c (async/promise-chan)]
(.then p
(fn [res]
(if (nil? res)
(async/close! c)
(async/put! c res)))
(fn [err]
(async/put! c
(ex-info "Promise error"
{:error :promise-error}
err))))
c))
make a channel, use the then of the promise to put on the channel. same idea here. make a promise, when you take from the channel resolve the promise with it
Thanks:smiley: I am on chapter 4 of Brave True now
Unless I am mistaken, it looks like having a namespace ending in 'init' (eg. my.namespace.init
) completely breaks things. It compiles without a fuzz but other namespaces are loaded as undefined. Does it make sense? Using Shadow-CLJS
There is something else at stake... My namespace which is pretty much empty is loaded but results in being undefined when used somewhere else... I've spent hours on this
If it still doesn't work after clearing everything build-related, can you create a minimal reproducible example and share the link to its repo?
if you get an exception during load that may prevent the namespace from being created. check the browser console.
other than that my.namespace.init
is completely fine and should work
It's madness, utter madness. I've spent a whole day on this!
Never ever have I encountered something as maddening and I had my fair share of weird behavior with CLJS...
I have a CLJC file in a folder. At this point it's just a namespace with (def foo 42)
as a test. When required from a CLJS file, everything is fine, I can access foo
. When required from a CLJC file, then suddenly everything breaks. The namespace becomes undefined, even in CLJS. Compilation is fine, requiring is fine (error comes when trying to access foo
on undefined later).
But wait it gets worse. This very same file, when put in another folder works right away from everywhere. I have a cursed folder name piece
and any CLJC file inside of it, when required from another CLJC file, produces this behavior.
It's not about permissions, I have even re-created that folder to make sure. I have literally DOZENS of other CLJC files required by CLJC files. It's just about that damn piece
folder. Works with piece2
.
Furthermore, the JS output file looks absolutely fine.
Clearing .shadow-cljs
, .cpcache
and all compiled JS files, the browser cache... doesn't make a difference.
Please create a minimal reproducible example.
just run shadow-cljs browser-repl
and then (require 'my.namespace.init)
what does "the namespace becomes undefined" even mean?
do you get any warnings? do you maybe have (ns my.namespace.init)
and also (ns my.namespace) (defn init []...)
?
it is rather unlikely this has anything to do with caching and so on so rather look in your own code for causes
No warnings at all, and I can require and use this namespace from the browser-repl
just as from any Clojurescript file. "becomes undefined" means that when it is required from a CLJC file, then is sorts of suddenly disappear. When I try to access a var such as foo
from the REPL or anywhere in my code, I get a TypeError: Cannot read property 'foo' from undefined
.
And it's so weird I have to repeat it, it only happens with namespaces in that one folder. I really can't see what could produce this mystery in my own code or code organization, I am following the same simple structure I've been using for dozens of files... I'll try to make a repro case but since I have no idea what is going on, I'm not sure I'll succeed (and I cannot share the source of this quite massive commercial project).
Hello. Can you post this in #calva?