This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-01-27
Channels
- # announcements (10)
- # aws (11)
- # beginners (158)
- # calva (8)
- # cider (14)
- # clj-kondo (1)
- # cljsrn (1)
- # clojure (83)
- # clojure-europe (5)
- # clojure-italy (25)
- # clojure-nl (3)
- # clojure-spec (12)
- # clojure-uk (20)
- # clojurescript (72)
- # community-development (18)
- # core-async (4)
- # core-logic (19)
- # cursive (11)
- # datomic (21)
- # duct (6)
- # events (1)
- # figwheel-main (3)
- # fulcro (15)
- # ghostwheel (1)
- # jobs (1)
- # leiningen (16)
- # off-topic (45)
- # onyx (3)
- # pathom (7)
- # perun (1)
- # ring (3)
- # shadow-cljs (48)
- # spacemacs (10)
- # specter (1)
- # sql (24)
- # tools-deps (7)
- # vscode (7)
- # xtdb (14)
It is not. :)
CLJS has ex-info
that creates an instance of ExceptionInfo
. But you don't have to use it - you can catch
anything that you can throw
. Including JS exceptions.
Has anyone had an issue importing vega libraries in clojurescript? I’m getting the following error in my browser when attempting to convert a vega spec into an actual graph:
failed to load module$node_modules$vega_lite$build$vega_lite.js SyntaxError: "missing ) after for-loop control"
globalEval
evalLoad
<anonymous>
Looks like something that the Google closure compiler is doing weirdly… Other warnings include:
failed to load cljsjs.vega_lite.js Module not provided: module$node_modules$vega_lite$build$vega_lite app.js:2218:15
shadow-cljs - failed to load module$node_modules$vega_embed$build$vega_embed /js/compiled/cljs-runtime/shadow.js.js:39:17
failed to load cljsjs.vega_embed.js Module not provided: module$node_modules$vega_lite$build$vega_lite
The exception is:
ReferenceError: vegaEmbed is not defined
We’re importing the vega components via ShadowCljs, relevant config in package.json:
{"dependencies":
[...]
"vega": "^5.9.1",
"vega-embed": "^6.2.2",
"vega-lite": "^4.0.2"
[...]
}
"missing ) after for-loop control"
sounds like your Vega spec is incorrect.
I've used Vega with CLJS, although it was not the Vega-Lite version.
Weird thing is, the page renders fine (with the vega viz) in Safari, but not in Firefox or Chrome…
@U2FRKM4TW what did you use for dependency management when you used vega?
Yeah, it's not your spec. Does that SyntaxError
give any details about the line number?
I used NPM + shadow-cljs + deps.edn.
here it is with line numbers included:
failed to load module$node_modules$vega_lite$build$vega_lite.js SyntaxError: "missing ) after for-loop control" app.js:2218:15
globalEval
evalLoad
<anonymous>
Ah, by default shadow-cljs uses :devtools {:loader-mode :eval}
which messes up the line numbers since now the code is not in a separate file but in the same app.js
.
so after putting together a bare-bones example, it’s all working. I suspect that using lein with shadow got very messy, and compilation is stuffing up somewhere. I can send the lein config if you’re a glutton for punishment, but otherwise let’s leave it here 😄
OK. Well, the above exception doesn't sound like anything that would result from using lein.
Try setting :loader-mode
to some value other than :eval
and see what line number it gives you, then see what's at that line. Should be a messed up for
loop.
We got a different error output this time!
SyntaxError: missing ) after for-loop control module$node_modules$vega_lite$build$vega_lite.js:370:209
uncaught exception: Module not provided: module$node_modules$vega_lite$build$vega_lite js.js:88:4
jsRequire js.js:88
require js.js:100
<anonymous> cljsjs.vega_lite.js:3
uncaught exception: Module not provided: module$node_modules$vega_lite$build$vega_lite js.js:88:4
jsRequire js.js:88
require js.js:100
<anonymous> cljsjs.vega_embed.js:3
for what it’s worth, all the modules that are said not to be provided have been installed via npm and included as dependencies in lein
It says "not provided" probably because of that SyntaxError
- the module was provided, it just couldn't be loaded.
So, if you now open module$node_modules$vega_lite$build$vega_lite.js:370:209
, what's in there?
I’m very sorry but need to head off - really appreciate your help! do you mind if I pick up this thread again tomorrow?
Don't mind at all - add more details whenever you can. Regardless of what we find at that particular line/column, my next steps would probably be: 1. Try to build the CLJS code using only shadow-cljs, with no lein and lein-shadow at all 2. Try to remove all of the app code except the one that creates the Vega chart 3. Remove CLJS dependencies that now aren't used, one by one Between all points, check whether the app works.
Since your app doesn't work but the minimal example does, this process would allow us to find that point of breakage. Of course, you can go the other way - try to build up on that minimal example till it breaks. Up to you.
@U2FRKM4TW quick update on this: I took all existing code and did the following differently:
• ran it using shadow-cljs.edn instead of a project.clj
• upgraded to reagent 0.9.1 from 0.8.0 due to a TypeError
when using :>
(see here: https://github.com/reagent-project/reagent/commit/60f7b4bc0c27672459a7a9babf22be2465258e4f)
It all works now…
or anyone that can provide a basic working example figwheel-main conf/setup that passes Chrome's security checks?
Hi, I have JS object that prints like that: #object[Error]
How can I convert it to Clojure Exception? so I can use it with Timbre logging
@feikas If I remember correctly, if you pass the exception as the first argument to error
it will log the stacktrace of that exception
Hi there. I'm new here. Anybody knows what is the best way to interop with (iterate over) Map object. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
@marko.horvatic You could first translate it to a CLJS map with js->clj
and then iterate over that, if performance is not that important
@borkdude Well Map is I guess a bit tricky
(seq (js->clj (js/Map. (clj->js [["a" 1]]))))
#object[Error Error: [object Map] is not ISeqable]
hmm, I see. I read something about this: https://twitter.com/swannodette/status/533354821999677440?lang=en but I have no clue sorry 🙂
np, thanks anyway.
Given what borkdude has posted, you can do it like this:
cljs.user=> (vec (es6-iterator-seq (.entries (js/Map. #js [#js ["a" 1] #js ["b" 2]]))))
[#js ["a" 1] #js ["b" 2]]
If you work with js/Map
s all the time and don't really care about both the performance and the advice to not extend built-in types, you can probably (extend-type js/Map IEncodeClojure (-js->clj [x opts] ...))
.
@U2FRKM4TW Thanks for the answer.
It is not that often. I have isolated case of external dependency that feeds me with js/Map data.
About your response, I can see es6-iterator-seq
is marked as experimental https://cljs.github.io/api/cljs.core/es6-iterator-seq Does this pose any risk?
I doubt that it will be removed completely, maybe only changed somehow. It has been there for 6 years. Also, its implementation is so trivial, you can just copy-paste it into your own project (maybe just name it differently to avoid shadowing CLJS of the core symbol).
👍 thanks
Hi, I have JS object that prints like that: #object[Error] How can I serialize it with pr-str
so it can be read after with read-string
? js->clj does not help
To print it in some way that allows reconstructing the object later, you have to extend-type
the js/Error
to support the IPrintWithWriter
protocol.
To read it back (assuming, you're talking about cljs.reader/read-string
), you need to add a custom reader to cljs.reader/*tag-table*
.
I’ve been working with SPAs and re-frame for a bit, but I’m looking at reitit and front end routing for the first time. Other than making the app browser-friendly re: history, what else will a front end router do for me?
I use reitit-frontend to decide which view to render and to run initialization code on page change (controllers). There are also nice utils to coerce data from path and query parameters.
It’s nice to be able to annotate your routes with arbitrary data: required roles for routes, layout info, attached view components etc. Also, as the route data accumulates from root to the leaves, you can have a "/admin"
route fragments with user role requirements that effect all the child routes.
(def router
(rf/router
[["/" {:name ::home
:icon "inbox"
:view [:h1 "home!"]
:title "Kotisivu"}]
["/gallery" {:name ::gallery
:icon "desktop"
:title "Gallery"
:view demo.gallery/form-view}]
["/admin" {:roles #{:admin}}
["/users" {:name ::users
:view demo.admin/user-view}]
["/orders" {:name ::orders
:view demo.admin/order-view}]]
["/schema" {:name ::poc
:icon "line-chart"
:title "Schema"
:view [demo.schema/form-view]}]
["/user" {:name ::user
:icon "user"
:title "Käyttäjä"
:view user-view}]]))