This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-07-17
Channels
- # beginners (42)
- # cider (1)
- # cljs-dev (20)
- # clojure (73)
- # clojure-italy (8)
- # clojure-nl (53)
- # clojure-spec (11)
- # clojure-uk (88)
- # clojurescript (170)
- # clojutre (6)
- # core-async (26)
- # css (2)
- # cursive (13)
- # data-science (10)
- # datomic (15)
- # editors (3)
- # figwheel (28)
- # figwheel-main (67)
- # fulcro (57)
- # graphql (2)
- # immutant (2)
- # jobs (1)
- # jvm (4)
- # lein-figwheel (3)
- # leiningen (1)
- # off-topic (5)
- # pedestal (28)
- # re-frame (86)
- # reagent (18)
- # reitit (8)
- # ring (3)
- # ring-swagger (2)
- # shadow-cljs (78)
- # spacemacs (10)
- # specter (12)
- # tools-deps (32)
- # vim (3)
What are the differences between the browser and node: https://clojurescript.org/reference/compiler-options#target If I intend to make a cljs library used by JS code, is there a way to make it work for both (like some NPM packages do)?
So I have this that works in the repl
(def m {:id 1 :name "Jane Doe"})
(-> m vals string/join)
"1Jane Doe"
however in the browser. in a reagent component
I can't do this
(js/console.log (-> m vals string/join))
TypeError: me.cljs$core$IMapEntry$_val$arity$1 is not a function
which implies I am trying to call a map as a function
when I take out the string/join
I get a weird object along these lines
(js/console.log (-> m vals))
Object { mseq: {…}, _meta: null, "cljs$lang$protocol_mask$partition0$": 32374988, "cljs$lang$protocol_mask$partition1$": 0 }
Another thing I have data from a cljs file and when I try to call vals I get an error:
(-> map vals)
== JS EXCEPTION ==============================
ENCODING FAILED
==============================================
Another thing (-> map vals (partial string/join " ") )
gives me a result such as #object[G__24608]
instead of a string joined with spaces
@urbanslug do you have https://github.com/binaryage/cljs-devtools installed? should make it much easier figuring out what objects are in your map
@thheller the problem with encoding is only in the repl and doesn't bother me much because I'm just testing stuff out
the ENCODING FAILED
just means that the REPL failed to pr-str
the result of you eval
@thheller I have this in my source file
(def columns [:id :name])
(defrecord data-generator [id name])
(def data
[(->data-generator 123 "Von Dutch")
(->data-generator 311 "Joms Viking")])
in the repl
=> data
[{:id 123, :name "Von Dutch"} {:id 311, :name "Joms Viking"}]
=> (-> data vals)
== JS EXCEPTION ==============================
ENCODING FAILED
==============================================
> it can't transmit the encoded version back to your REPL output
Ah @thheller then that would make sense because whenever I call vals
in my component I get weird errors and even when I js/console.log it it gives a weird object
it's not exactly like that it's
[#example.components.views.table.data-generator{:id 123, :name "Von Dutch"} #example.components.views.table.data-generator{:id 311, :name "Joms Viking"}]
My bad. tried again for the map and failed
(-> data first map?)
true
(-> data first vals)
== JS EXCEPTION ==============================
ENCODING FAILED
==============================================
[1:1]~demo.browser=> (defrecord Foo [a b])
demo.browser/Foo
[1:1]~demo.browser=> (vals (->Foo 1 2))
I was starting to consider calling js functions like so
(def js-obj (-> data first clj->js))
(.values js/Object m)
Found a thread here https://groups.google.com/forum/#!topic/clojurescript/e9qAk1gqgS4
@thheller a little help there's something weird here.
[1:1]~demo.browser=> (def x (first data))
[1:1]~demo.browser=> (vals (into {} x))
(123 "Von Dutch")
[1:1]~demo.browser=> (-> data first (partial into {}) vals)
nil
You didn't want to use partial
here. Macroexpanded, it'll look like (vals (partial into {} (first data)))
which, when executed, will try to call vals on a function. You want (->> data first (into {}) vals)
.
I think I'll leave the records alone for now:
[1:1]~demo.browser=> (->> data (map #(into {} %)) vals)
== JS EXCEPTION ==============================
ENCODING FAILED
==============================================
yeah this seems to work
(->> data (map #(into {} %)))
({:id 123, :name "Von Dutch"} {:id 311, :name "Joms Viking"})
what exactly is the problem though? AFAICT the problem only appears when trying to print the thing
I'm using a for loop in a reagent component and want to silence the warning about each element having a unique key
Hello. I need a hint for the following problem: When writing hiccup for re-frame, I often have a vector containing mostly static content: [:ul [:li "A"] [:li "B"] [:li "C"]]
. But sometimes I have to include values from an other sequence into my list. Here I need to include elements from the vector (def subitems ["B.1" "B.2"])
into my hiccup. Is there an elegant way to place some code between [:li "B"]
and [:li "C"]
which inserts elements from subitems
wrapped in [:li ...]
s?
I am looking for something which would be used like that: [:ul [:li "A"] [:li "B"] (magic-for [subitem subitems] [:li subitem]) [:li "C"]]
.
how about (->> (concat [:ul [:li "A"] [:li "B"]] (magic-for ...) [:li "C"]) (into []))
but in general it’s better to keep Hiccup static
unquote-splicing
should work here as well
`[1 2 3 ~@[5 6] 4] ;; [1 2 3 5 6 4]
`[:ul
[:li "A"]
[:li "B"]
~@(for [idx (range 2)]
[:li idx])
[:li "C"]]
;; => [:ul [:li "A"] [:li "B"] [:li 0] [:li 1] [:li "C"]]
So what does this message mean? -> WARNING: Use of undeclared Var cljs.core/unquote-splicing at line 63
I wonder if this unquote splicing on for loop, takes its lazyness into account. Never tried this, always use into myself.
@witek hmm, perhaps it doesn’t work when compiled since cljs doesn’t include the whole compiler/reader into output JS
just tried it with :none
optimizations, works fine
I think I've hit a strange issue with ClojureScript self hosted REPLs and I can't tell if it's a bug or if I'm misunderstanding: This works (on http://clojurescript.io):
cljs.user=> (ns macros.core$macros) (defmacro hello [x] (prn &form) `(inc ~x))
true
macros.core$macros=> (macros.core/hello 1)
2
This does not (on a fresh page load)
cljs.user=> (do (ns macros.core$macros) (defmacro hello [x] (prn &form) `(inc ~x)))
true
macros.core$macros=> (macros.core/hello 1)
ERROR - undefined is not an object (evaluating 'macros.core.hello')
The only difference here is that I've wrapped everything in a do
form in the second example. Curiously, if I repeat said form... it works!
cljs.user=> (do (ns macros.core$macros) (defmacro hello [x] (prn &form) `(inc ~x)))
true
macros.core$macros=> (do (ns macros.core$macros) (defmacro hello [x] (prn &form) `(inc ~x)))
true
macros.core$macros=> (macros.core/hello 1)
2
I thought perhaps do
was lazily computing something, but documentation doesn't seem to indicate this is the case. Curiously... after the first do
form, macros.core
is {}
rather than the expected {hello: [Function]}
Perhaps do is introducing an additional (JS) scope that is mucking up how namespaces work in ClojureScript?Going down a layer, good code:
goog.provide("macros.core$macros");
(function (){
(function (){
macros.core$macros.hello = (function macros$core$macros$hello(_AMPERSAND_form,_AMPERSAND_env,x){
cljs.core.prn.call(null,_AMPERSAND_form);
return cljs.core.sequence.call(null,cljs.core.concat.call(null,cljs.core._conj.call(null,cljs.core.List.EMPTY,new cljs.core.Symbol("cljs.core","inc","cljs.core/inc",(-879172610),null)),cljs.core._conj.call(null,cljs.core.List.EMPTY,x)));
}); return (
new cljs.core.Var(function(){return macros.core$macros.hello;},new cljs.core.Symbol("macros.core$macros","hello","macros.core$macros/hello",(-113529239),null),cljs.core.PersistentHashMap.fromArrays([new cljs.core.Keyword(null,"ns","ns",(441598760)),new cljs.core.Keyword(null,"name","name",(1843675177)),new cljs.core.Keyword(null,"file","file",(-1269645878)),new cljs.core.Keyword(null,"end-column","end-column",(1425389514)),new cljs.core.Keyword(null,"column","column",(2078222095)),new cljs.core.Keyword(null,"line","line",(212345235)),new cljs.core.Keyword(null,"macro","macro",(-867863404)),new cljs.core.Keyword(null,"end-line","end-line",(1837326455)),new cljs.core.Keyword(null,"arglists","arglists",(1661989754)),new cljs.core.Keyword(null,"doc","doc",(1913296891)),new cljs.core.Keyword(null,"test","test",(577538877))],[new cljs.core.Symbol(null,"macros.core$macros","macros.core$macros",(1865249614),null),new cljs.core.Symbol(null,"hello","hello",(1395506130),null),null,(40),(25),(1),true,(1),cljs.core.list(new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Symbol(null,"x","x",(-555367584),null)], null)),null,(cljs.core.truth_(macros.core$macros.hello)?macros.core$macros.hello.cljs$lang$test:null)])));})()
;
return macros.core$macros.hello.cljs$lang$macro = true;
})()
Bad code
(function (){
goog.provide('macros.core$macros');
goog.require('cljs.core');
(function (){
cljs.user.hello = (function cljs$user$hello(_AMPERSAND_form,_AMPERSAND_env,x){
cljs.core.prn.call(null,_AMPERSAND_form);
return cljs.core.sequence.call(null,cljs.core.concat.call(null,cljs.core._conj.call(null,cljs.core.List.EMPTY,new cljs.core.Symbol("cljs.core","inc","cljs.core/inc",(-879172610),null)),cljs.core._conj.call(null,cljs.core.List.EMPTY,x)));
}); return (
new cljs.core.Var(function(){return cljs.user.hello;},new cljs.core.Symbol("cljs.user","hello","cljs.user/hello",(-1955175765),null),cljs.core.PersistentHashMap.fromArrays([new cljs.core.Keyword(null,"ns","ns",(441598760)),new cljs.core.Keyword(null,"name","name",(1843675177)),new cljs.core.Keyword(null,"file","file",(-1269645878)),new cljs.core.Keyword(null,"end-column","end-column",(1425389514)),new cljs.core.Keyword(null,"column","column",(2078222095)),new cljs.core.Keyword(null,"line","line",(212345235)),new cljs.core.Keyword(null,"macro","macro",(-867863404)),new cljs.core.Keyword(null,"end-line","end-line",(1837326455)),new cljs.core.Keyword(null,"arglists","arglists",(1661989754)),new cljs.core.Keyword(null,"doc","doc",(1913296891)),new cljs.core.Keyword(null,"test","test",(577538877))],[new cljs.core.Symbol(null,"cljs.user","cljs.user",(877795071),null),new cljs.core.Symbol(null,"hello","hello",(1395506130),null),null,(44),(29),(1),true,(1),cljs.core.list(new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Symbol(null,"x","x",(-555367584),null)], null)),null,(cljs.core.truth_(cljs.user.hello)?cljs.user.hello.cljs$lang$test:null)])));})()
;
return cljs.user.hello.cljs$lang$macro = true;
})()
You'll note that the bad code directly assigns to cljs.user.hello
. What?Hmm, so the ClojureScript compiler produces different JS for the first do and the second do
Hi ! Does anyone could advise me for some open source project that i can cooperate and improve my skills in Clojure(script) ?
(FWIW, I tried the equivalent in straight Clojure and the behavior is the same with and without the do)
here's a dumb question: What's the purpose of cljs-devtools https://github.com/binaryage/cljs-devtools? To get better errors?
I’d say “more cljs-friendly debugging output” — it lets you display cljs data structures you can inspect instead of just displaying #object[my.ns.Baseclass]
. If you run cljs without the devtools and you do something like (prn {:foo 1 :bar 2})
, and then do the same with devtools (and with custom formatters enabled) you’ll see the difference.
OK thanks thing is I was using firefox and earlier today someone mentioned it would help with my errors. Also on chromium react devtools are able to notice that I'm using react
What are the best recommended resources to give to a team who is new to clojurescript?
@joshua.d.horwitz what are you looking for? more specifically
So basically I have a JavaScript/Node/React team, with no Clojurescript experience. When introduction say React, I had a few books I could give them and some training sites, looking at how to do that with Clojurescript/reframe
so http://purelyfunctional.tv has a bunch of resources for front-end work
@joshua.d.horwitz these are high quality recent resources
Great, thank you so much
@joshua.d.horwitz https://www.packtpub.com/web-development/learning-clojurescript may have the distinction of being the most recent work
I'm currently working on documentation for figwheel-main
and the tutorial http://rigsomelight.com/figwheel-main/tutorial is fairly extensive
and there is of course this https://clojurescript.org/guides/quick-start
@joshua.d.horwitz that should be enough to get you started 🙂
That's perfect! Thank you so much
@joshua.d.horwitz oh I didn't mention this because its such a well known Clojure resource https://www.braveclojure.com/clojure-for-the-brave-and-true/
If you'd like to try out a pre-release of a new Graal.js REPL environment for ClojureScript, instructions here https://gist.github.com/mfikes/e0dcb57f2d87afc905829f86111fb610 Here is using it to calculate the sum from 1 to 100 with five languages in one REPL. 🙂
cljs.user=> (reduce + (range 1 101))
5050
cljs.user=> (.eval js/Polyglot "R" "sum(1:100)")
5050
cljs.user=> (.eval js/Polyglot "ruby" "(1..100).reduce(:+)")
5050
cljs.user=> (.eval js/Polyglot "python" "sum(x for x in range(1, 101))")
Error: Operation is not allowed for: /private/tmp/graaljs
cljs.user=> (.eval js/Polyglot "python" "sum(x for x in range(1, 101))")
5050
cljs.user=> (.eval js/Polyglot "js" "(100 * (100 + 1)) / 2")
5050
Hello, when it comes to routing I'm using secretary and accountant. I'm not using fragments for my routes. What I've noticed is on gitlab pages my routes fail, it tries to load another page and gets a 404/
I've been looking at https://en.wikipedia.org/wiki/Fragment_identifier
and it seems I ave to use the #
for routing in SPAs but is this really not because of gitlab pages?
@urbanslug you'll need to use # routing, yes
in order to use non-# routing for SPAs you need to configure your webserver in a certain way. github pages does not allow you to do that configuration
* or use the history api, right? thats purely client-side and removes the # i thought.
I'm willing to do this. So if I use the history API this could work? > or use the history api, right? thats purely client-side and removes the # i thought.
I guess I should say, I have a CLJS app that runs on Node.js - is it possible for me to get a REPL in it once it's deployed?
@lilactown You could consider running things in a self-hosted compatible way
This project is probably the easiest path to success for doing something like that https://github.com/Lambda-X/replumb
I'm trying to get some performance info so I'm hesitant to switch to self hosting 😭
hey everyone, I'm trying to write a data_readers.cljc file so that different output is produced if a reader fn is being run when reading clojurescript than when reading clojure. I know I could not use data_readers.cljc file and manually set! data-readers but would like to do it via the file if possible. using reader conditionals won't work afaik because in the case of non-self-hosted cljs the code that's running is actually clojure. any ideas please let me know
@urbanslug the issue is that if you reload a non-fragment route or just cut-and-paste it into a fresh browser window, the browser will try to go fetch that page. the typical fix for this is to redirect everything to index.html
so that it just loads up your spa and then the router will load the right page based on the url. gitlab pages doesn’t have support for that, apparently https://gitlab.com/gitlab-org/gitlab-pages/issues/23
@lee.justin.m a freaking life saver you are!
@witek @roman01la if you are writing hiccup for re-frame/reagent, I don’t see any real advantage trying to keep hiccup static. arguably one of the nicest (and confusing) aspects of reagent is that it adds one more layer of indirection over react, which enables you to create hiccup structures dynamically using all the normal collection functions (like into
). there isn’t really any such thing as “static” hiccup in reagent, unless i misunderstand what you guys mean
@justinlee Static hiccup with ~@(...)
at some places is much more readable then a threading macro and into
. When reading my view code I need to see HTML concepts immediately. Not how it is constructed. When prettyfying my UI I need to move div
s, wrap and unwrap them with other div
s and so on. This is much easier when there are just hiccup vectors not mixed with collections concepts.
You shouldn't need to deal with quoting and splicing. Just leave stuff as non-vector seqs.
yea so @witek the magic-for
you are looking for is really just regular old for
:
(defn test-component
[]
[:div [:div "a"]
(for [x (range 1 10)] ^{:key x} [:div x])
[:div "b"]])
You just need to set a key to avoid the warning. You could write a for-wrapper that just sets the key equal to the index to shorten it up.Hey, what do you people use for the most robust solution for routing in your SPA? Something that will keep the animations alive (best probably would be without switching components). Cheers!
I am using bidi + goog.History (https://github.com/nenadalm/Warehouse/blob/d29bd308d5cf6697bd22cb138d26e5b271b3a2fe/frontend/src/warehouse/routes.cljs#L25).
Can anyone help with the magic incantation of the ClojureScript real to give me verbose output?
(require '[cljs.repl :as repl])
(require '[cljs.repl.node :as node])
(def env (node/repl-env :repl-verbose true))
(repl/repl env)
@marcinszyszko I don’t know about animations. I have used secretary
+ accountant
and it is simple and serviceable. I suppose you could use interop to use react router, which will do everything, obviously.
Thanks @lee.justin.m. Secretary works as a charm here, but the project is no longer maintained.
Thanks @bhauman!
@josh_horwitz do look at this page: https://purelyfunctional.tv/framework/re-frame/ There's plenty of free guides and there's a couple of paid video courses.
I'm trying to test out node's new worker_threads
module: https://nodejs.org/api/worker_threads.html
I updated this line to use the experimental --experimental-worker
flag: https://github.com/clojure/clojurescript/blob/5dc641ed1bf5ea642a9cb00f0fc770eb479c23bb/src/main/clojure/cljs/repl/node.clj#L115
Using the new cljs test-runner, (nodejs/require "worker_threads")
, I constantly get Error: Cannot find module 'worker_threads'
@john If it helps, I had made a similar revision that adds extra args to node
https://github.com/mfikes/clojurescript/commit/3e13026898acaa0f89eaa6eaa3be9411e084cf2d
I am trying to use om.next to write a custom shouldComponentUpdate
override. If I need to access the clojure-friendly state value in my component code, is using goog.object/get
in this fashion https://github.com/omcljs/om/blob/master/src/main/om/next.cljc#L203-L205 the way you are supposed to access state (without the macro parts)?
I’m used to using the api methods like om.next/get-state
for cases like defining the render function, but after looking through the docs couldn’t locate guidance for this situation.
I decided to ignore the next-state
argument, and use om/get-rendered-state
to get the current state, and om/get-state
to get the next state.