This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-07-20
Channels
- # announcements (1)
- # babashka (32)
- # beginners (100)
- # cider (43)
- # clj-kondo (4)
- # cljdoc (3)
- # cljs-dev (5)
- # cljsjs (2)
- # cljsrn (22)
- # clojure (170)
- # clojure-australia (27)
- # clojure-europe (25)
- # clojure-nl (3)
- # clojure-uk (76)
- # clojurescript (127)
- # conjure (14)
- # core-matrix (1)
- # cursive (9)
- # datomic (6)
- # defnpodcast (1)
- # emacs (32)
- # events (1)
- # expound (77)
- # fulcro (30)
- # graalvm (21)
- # graalvm-mobile (30)
- # helix (4)
- # honeysql (1)
- # hyperfiddle (1)
- # jackdaw (8)
- # jobs (6)
- # kaocha (1)
- # leiningen (4)
- # lsp (16)
- # malli (46)
- # meander (4)
- # off-topic (19)
- # pathom (10)
- # podcasts (1)
- # portal (2)
- # re-frame (7)
- # reagent (2)
- # releases (1)
- # remote-jobs (11)
- # rewrite-clj (8)
- # shadow-cljs (9)
- # tools-deps (243)
- # vim (1)
Quick sanity check. I'm having trouble requiring a node module where default
is name mangled to default$
then doesn't resolve correctly.
This...
(ns interop.masked-input
(:require [react-text-mask :as MaskedInput]
[reagent.core :as r]))
(def masked-input (r/adapt-react-class MaskedInput/default))
Turns into
// Compiled by ClojureScript 1.10.773 {:target :nodejs}
goog.provide('interop.masked_input');
goog.require('cljs.core');
goog.require('reagent.core');
interop.masked_input.node$module$react_text_mask = require('react-text-mask');
interop.masked_input.masked_input = reagent.core.adapt_react_class.call(null,interop.masked_input.node$module$react_text_mask.default$);
with cljsrn I happily set :language-out to something very recent. is that the safe/correct approach for web browser targets?
I think this indicates I can feel good about compatibility with :language-out :es6
https://caniuse.com/?search=es6
hmm. wild guess here but would the following work?
(ns interop.masked-input
(:require [react-text-mask :default MaskedInput]
[reagent.core :as r]))
(def masked-input (r/adapt-react-class MaskedInput))
Does anyone know how to translate this into clojurescript ...
<MapConsumer>
{(map) => {
console.log('map center:', map.getCenter())
return null
}}
</MapConsumer>
I only know I can do
[:> MapConsumer]
but i'm not sure how to do the arrow function and where it should beThe function is correct, but if it's reagent land you're looking at something like [MapConsumer {} (fn ...)]
Honestly, that's something I'm asking myself now. Leaflet react doesn't have amazing documentation https://react-leaflet.js.org/docs/api-map/#mapconsumer but using leaflet directly and creating my own reagent components is too tough for me for now
@lsenjov just so that I don't get stuck if I need this ... do you happen to know how to the equivalent for ^
(fn my-comp [] (js/console.log (.getCenter (js/useMap))))
(fn my-map-comp [] [(adapt-react-class MapContainer) {:center [50.5 30.5] :zoom 13} [my-comp]])
console.log
returns null anyway, so we shouldn't need to do any let
bindings in there
Note again that this is reagent land, I'm not sure how this works in react cljs or raw cljs
I can only guess - but do you see any errors about my-comp not being a valid component? It doesn’t have any visual elements in it, and I’d guess reagent barfs at that. I don’t know the purpose of my-comp, but a crude attempt could be to wrap it in a [:div…
and display: none
it and figure out the logic part?
@jaju @lsenjov okay will try that. I think this isn't as important for now. Will look into it again if I encounter it again :x but thank for your help!!
Hey, I build the app with shadow-cljs release app
, filling the release/public
dir with js files [app.js, utils.js]
and no html files. So for run the static app I added a page.html
importing css
and js
files in order or dependency. Everything is loaded without console error, but the page is blank. What I'm missing?
Stupid question - did you call the init
-equivalent JS function in the HTML? Or, is it called by default in your main namespace, so as the initialize the app?
@eliascotto94 what is in your html used for the development builds?
@thheller I don't use any html for the build. Is created in Clojurescript when the user go on the route (reitit-ring/router [["/" {:get {:handler index-handler}}]])
index-handler
is a hiccup component
(def mount-target
[:div#app
[:h2 "Welcome to 7GUIs"]
[:p "please wait while shadow-cljs is waking up ..."]
[:p "(Check the js console for hints if nothing exciting happens.)"]])
(defn head []
[:head
[:meta {:charset "utf-8"}]
[:meta {:name "viewport"
:content "width=device-width, initial-scale=1"}]
(include-css (if (env :dev) "/css/site.css" "/css/site.min.css"))])
(defn loading-page []
(html5
(head)
[:body {:class "body-container"}
mount-target
(include-js "/js/utils.js")
(include-js "/js/app.js")
[:script "sevenguis.core.init_BANG_()"]]))
(defn index-handler
[_request]
{:status 200
:headers {"Content-Type" "text/html"}
:body (loading-page)})
I'm using this template https://github.com/reagent-project/reagent-templateloading-page
is your html and this emits a <script>
tag calling your init function. so thats missing from your page.html
if you want to do it correctly you remove that script tag entirely and in your build config use :init-fn
to call it for you. if you prefer to keep the script tag you need to ^:export
your init!
function. so (defn ^:export init! [] ...)
:modules {:utils {:entries [sevenguis.utils]}
:app {:entries [sevenguis.core]
:depends-on #{:utils}
:init-fn sevenguis.core/init!}}
but I get an error
An error occurred when calling (sevenguis.core/init!)
Uncaught Error: No matching clause:
well you are using a router. so I suspect that it doesn't have a proper route? what is the rest of the stacktrace?
the template you used seems to expect some kind of server? if you just have a static html file things might be different
An error occurred when calling (sevenguis.core/init!) app.js:979:357
Uncaught Error: No matching clause:
QD file:///Users/elia/dev/elias94.github.io/js/app.js:580
VD file:///Users/elia/dev/elias94.github.io/js/app.js:581
AA file:///Users/elia/dev/elias94.github.io/js/app.js:433
VD file:///Users/elia/dev/elias94.github.io/js/app.js:581
<anonymous> file:///Users/elia/dev/elias94.github.io/js/app.js:979
<anonymous> file:///Users/elia/dev/elias94.github.io/js/app.js:980
app.js:580:376
I don't know about the route because if i run shadow-cljs watch app
works correctly. So I suspect it expect a server, which I don't need because is a static app. I will remove all the unnecessary stuff from the template or switch to a new one. Thanks in the meantime, I love this community!you can try shadow-cljs release app --debug
to get a better idea whats actually wrong
my guess would be that you have a router and a case
somewhere that usually expects a "/"
or so route which now doesn't exist
An error occurred when calling (sevenguis.core/init!) append.js:2:57
Uncaught Error: No matching clause: core.cljs:856:2
$sevenguis$core$page_for$$ core.cljs:856
$sevenguis$core$init_BANG_$$/< core.cljs:887
$accountant$core$dispatch_current_BANG_$$ core.cljs:169
$sevenguis$core$init_BANG_$$ core.cljs:893
<anonymous> append.js:2
<anonymous> app.js:14733
cljs/core
(defn page-for [route]
(case route
:index #'home-page))
(defn current-page []
(fn []
(let [page (:current-page (session/get :route))]
[:div
[page]
[:footer
[:p]]])))
(defn mount-root []
(rdom/render [current-page] (.getElementById js/document "app")))
(defn init! []
(accountant/configure-navigation!
{:nav-handler
(fn [path]
(let [match (reitit/match-by-path router path)
current-page (:name (:data match))
route-params (:path-params match)]
(session/put! :route {:current-page (page-for current-page)
:route-params route-params})
(clerk/navigate-page! path)))
:path-exists?
(fn [path]
(boolean (reitit/match-by-path router path)))})
(accountant/dispatch-current!)
(mount-root))
clj/handler
(def app
(reitit-ring/ring-handler
(reitit-ring/router
[["/" {:get {:handler index-handler}}]])
(reitit-ring/routes
(reitit-ring/create-resource-handler {:path "/" :root "/public"})
(reitit-ring/create-default-handler))
{:middleware middleware}))
as I said. see the case route
. that doesn't have a default case so it fails since you are not getting :index
can't see your router
so not sure what you actually get, server side parts don't matter here
I have an issue with Re-frame's event handler reg-event-db
i am trying to, by clicking a button, to add extra information into an array in the appdb. But what is currently happening is that the data that is stored in the key is being replaced
how do i make sure that the data is added to the array?
code:
(reg-event-db
:fetch-data
(fn [db [_ map]]
(let [{:keys [a]} map]
(assoc-in db [:data :a] a))))
and currently in the appdb :data :a holds [1,2,3]
and i am trying to add 4,5,6
so it becomes [1,2,3,4,5,6]
For future reference, there's #re-frame
But in this particular case, your question is actually about core Clojure API.
You're using assoc-in
that is designed to replace the value. You should use something else, like a combination of update-in
and into
.
oh ok, thanks
I did, am quite confused why I can't further access it using -property
(.. layer -feature -geometry -properties)
One small thing that's not that well documented but still is important - when you define a symbol that names a JS object, add ^js
in front of it, be it in a function signature, in a def
, in a let
- all the same.
I have no idea why you can't access -property
- maybe it's not there?
cljs.user=> (def x #js {:a #js {:b 1}})
#'cljs.user/x
cljs.user=> (.. x -a -b)
1
I can access up to -property
but although I can console.log out the javascript object if I will get something like `Cannot infer target type in expression (. (. (. (. layer -feature) -geometry) -properties) -gid)` when I add the -gid
part
`Cannot infer target type in expression` is a message from the compiler.
Add ^js
in front of layer
.
https://code.thheller.com/blog/shadow-cljs/2017/11/06/improved-externs-inference.html
The article above and the others that it links to provide an explanation that's much better and more detailed than the one I could come up with. ;)
@U2FRKM4TW for some reason, using aget
allows me to get the value and not the conventional method.
Seems like the clojurescript aget
docs tell me to use goog.object/get
As I said - simply do not use aget
for anything that's not a JS array.
goog.object/get
is a less convenient alternative to the direct interop with ^js
.
Right o: cause my issue was that when I console.log, with
(.. ^js layer -feature -geometry -properties -lu-desc)
I get undefined
but (goog.object/get (.. ^js layer -feature -geometry -properties) "lu-desc")
gives me "BUSINESS 2"
Oh, that is interesting - the compiler doesn't like dashes in property names, it seems.
Yeah, -lu-desc
gets converted to lu_desc
. Alright, this right here is a good use case for goog.object/get
then.
I pass my geojson data into leaflet first and then I'm accessing the :properties
of data in the popups
Ah, so you control the properties
, I see. Maybe it (or at least a field within it with a simple name) could be set to a CLJS object.
But if you're fine with interop or goog.object/get
, then there's no need.
Curious, does anyone not like hiccup in reagent? If so why? I’m trying to decide if I’ll go down that route or not for a hobby project
Check out this recent thread: https://clojurians.slack.com/archives/C03S1L9DN/p1626615590475200
I like the dx of editing hiccup but it does have a small performance impact, and can be tricky to parse
Hey. How do you import a font from ClojureScript? In JavaScript it's import "@fontsource/roboto", which imports css styles what's the ClojureScript equivalent? I'm using material-ui.
Just include the necessary CSS statement in a relevant CSS file. It's not CLJS- or JS-specific.
Ah, indeed. Will give it a go.
No CSS files are defined in the project though, it's all managed from ClojureScript.
I could but I have the font family defined in a theme file for configuring the material-ui theme.
With material-ui, you can define a theme object that you define to customize the theme.
Alright, so it just mentioned the font by name? Then simply put that <style>
above the main script tag.
body {
font-family: "Roboto", sans-serif;
}
?Ah, it's a self-hosted font. And I think import "@fontsource/roboto";
inlines that font in your JS bundle.
So it's more involved than just adding a tag. Your CSS above is an instruction to use the font, but it doesn't say where to get it from.
Three options that I know of:
• Make your backend serve that font and specify it with @font-face
in your CSS
• Inline the fonts yourself via a data URL inside @font-face
: https://gist.github.com/minosiants/9891317
• Use something like webpack to do it for you
One other option is to get the font from a CDN. It's like the first option above, but without hosting anything yourself.
Thanks, The CDN option works but I wanted to go with self hosting.
@olivergeorge should be ok - but note there's a better way now
Thanks David. I guess you mean the new approach to using https://clojurescript.org/guides/webpack but I might missing something. (The new webpack is https://ask.clojure.org/index.php/9602/recommended-webpack-config-for-clojurescript-bundle-target)
@rbowen I'm pretty sure that is not a JavaScript feature? that's a feature of build tooling
however this problem was already considered some time ago - the :bundle
target allows you to write these patterns outside of your ClojureScript
meaning we punted the problem to where it belongs - not in the language but in tooling
Makes sense.
So the tooling would be shadow-cljs? It should be able to handle that correct? I came across :ignore-asset-requires true|false
but it seems to have no effect when set to false, assuming it is true by default.
no support for css no. the ignore is only for npm packages that might want to require css directly which would otherwise break
Okay, got it, thanks.
Can someone point me in the right direction with regards to symbol resolution in CLJS? This will work in CLJ but not CLJS:
(resolve (:boo (clojure.edn/read-string (pr-str {:boo 'inc}))))
=> #'clojure.core/inc
In CLJS you’ll get an exception:
clojure.lang.ExceptionInfo :
java.lang.AssertionError : Assert failed: Argument to resolve must be a quoted symbol
clojurescript cannot do any runtime evaluation. the repl has some limited at dev time
One would think it should work since ns-publics
seems to work. Not sure if it survives :advanced
compilation
@beders all those things are macros. so they all work at compile time in a static context. none of them take any arguments that resolve at runtime since that is technically impossible with :advanced
if you ^:export
all the things that you want resolvable that still works and you can look up the things by name after. vars don't really exist though so you just get the thing not a var like you would in CLJ
trying not to pollute. So maybe something using ns-publics
or a hand-rolled mapping. All things I need to resolve are static.
does anyone know how I can print the value of an atom straight in the chrome console?
@luishendrix92 ClojureScript has deterministic munging