Fork me on GitHub
#clojurescript
<
2017-04-03
>
ClashTheBunny00:04:48

Hi, I'm having an issue with clojurescript after 1.9.473 not respecting my (:require [reagent.session :as session]). I can't find documentation as to why that would no longer work.

ClashTheBunny00:04:32

When I bump clojurescript to 1.9.495, session/put! no longer is found as a symbol, but reagent.session/put! works just fine.

qqq01:04:38

does midje.sweet not work for cljs ?

qqq01:04:52

(I'm using a cljc file -- ot works fine under clj, but under cljs, I'm getting midje.sweet errors)

adambros03:04:53

@qqq Pretty sure midje is clj only

qqq03:04:20

@adambros: just switched to clojure.test and all works fine

adambros05:04:51

yeah clojure.test requires get morphed to cljs.test when in a cljs file

hlolli09:04:35

what's the logic with goog.closure not fixing the access to .-pageX,.-pageY attribute of mousemove evetns. Using native js interop js/document.addEventListener works but not goog.closure.Events, only when it comes to these accessors. Only assumeing google developers are smarter people than me, than maybe .-pageX isn't recommented?

thheller09:04:07

@hlolli that probably is for historic reasons and I think pageX is not part of any spec, so browsers implemented it differently or not at all

hlolli09:04:21

yes I read something in that direction. The only accessor that doesn't get screwed up by page-scrolling is .-pageX. And as this works on firefox/chrome, then my compassion for those IE5- people is small.

thheller09:04:04

well then use the native thing

thheller09:04:33

closure has a different stance where compatibility matters

hlolli09:04:41

yes, I kinda answered maybe my own question πŸ™‚ I see they are very strict on compatability. On the other hand I feel safer using goog.closure with cljs. I guess this is just the way it should be.

thheller09:04:33

nah I haven't used the goog.events stuff for years

thheller09:04:58

the document.addEventListener support is pretty good these days

thheller09:04:38

last offender to not support it was IE6 i think

thheller09:04:41

which is basically dead

hlolli09:04:21

yes. Macht kaputt was euch kaputt macht.

thheller09:04:35

also it is very easy to leak event listeners with the closure stuff since you need to dispose them

thheller09:04:55

they won't go away by just removing the dom element and letting that GC

akiroz09:04:19

Anyone know if it's possible to build a JS library (CommonJS interface) using Clojure?

gklijs09:04:56

I think so, I remember seeing an re-frame based JS library.

thheller09:04:17

@akiroz yes possible, with some caveats though

akiroz09:04:35

any idea how I'd go about doing that? I can't seem to find any materials on this....

akiroz10:04:33

I'd imagine my lib would be shipped with the whole clojure runtime and google closure lib but since I'm targeting nodeJS it's probably fine~

thheller10:04:38

so you want to build a node-library only?

thheller10:04:57

I have something for that .. although its a bit alpha and I'm not really ready to release it yet

thheller10:04:03

but it works well enough

thheller10:04:37

{:id :library
  :target :node-library
  :output-to "out/demo-library/lib.js"
  :exports
  {:hello demo.lib/hello}

thheller10:04:45

you basically define a config file

thheller10:04:56

and the things the module wants to export

thheller10:04:36

so for that example var x = require("./lib.js"); x.hello("foo"); would work

thheller10:04:52

where hello is actually calling the cljs fn

thheller10:04:23

I can give you a quick rundown on how to use it if you want

akiroz10:04:27

Wow awesome! πŸ™‚ is that :node-library target in the master of cljsbuild?

thheller10:04:53

hehe no there is nothing like that in anything official

thheller10:04:58

its a custom tool I built

thheller10:04:44

but you can use it like cljsbuild in some sense

akiroz10:04:32

ahh alright, mind if I give it a spin? πŸ˜›

thheller10:04:26

you add [thheller/shadow-devtools "0.1.20170403"] to your :dependencies in project.clj

thheller10:04:47

can be in the :dev profile if you have that (note it is not a plugin but dependency)

thheller10:04:09

create a shadow-cljs.edn file in the root of your project, like the above

thheller10:04:15

lein run -m shadow.cljs.devtools.cli/dev library

thheller10:04:24

lein run -m shadow.cljs.devtools.cli/release library

thheller10:04:33

lein run -m shadow.cljs.devtools.cli/once library

thheller10:04:38

release for an optimized build

thheller10:04:46

once for just building once

thheller10:04:52

dev for hot-reload, repl stuff

rauh10:04:04

Is there an easy to way to generate some javascript from some clj forms? So without any goog.require/provide and without any cljs.core usage?

rauh10:04:46

Just some functions for a documentation page, an I don't want to write js. Doesnt' need minification or anything. I know I couldn't use destructing an many other forms.

thheller10:04:00

@rauh not really, some constructs assume the presence of cljs.core

akiroz10:04:41

@thheller cool, lemme try it out πŸ˜„

thheller10:04:42

@akiroz be warned though it is alpha. I have been using it for years but some things are new and may have some rough edges

thheller10:04:45

@rauh I have something you could use for that, but it would require some manual work

rauh10:04:03

@thheller That's what I thought. 😞 For instance if I have simple functions like:

(defn set_width []
  (let [el (.getElementById js/document "foo")]
    (set! (.. el -style -width) "400px")))
That wouldn't depend on anything. All I'd need is the clj->js transpilation stage.

rauh10:04:38

Or even (set! js/inc_width (fn [] ...).

rauh10:04:02

I guess I can just use a normal cljs file and strip the goog.provide/require calls at the beginning of the file...

rauh10:04:48

( via thheller: )

thheller10:04:44

you can also do that with cljs.compiler.api and cljs.analyzer.api btw

grumplet12:04:44

Just been through the examples in https://clojurescript.org/guides/javascript-modules. Very nice! For the example which uses nashorn to run babel and compile JSX in watch.clj, would there be a route to get a repl going yet?

tjtolton12:04:59

has anyone here worked with Quiescent? Specifically, the quiescent tutorial app, the TodoMVP app? I'm newcommer to clojurescript and javascript, so I'm having trouble understanding this line in the project.clj:

(defproject mvp-maze "0.1.0-SNAPSHOT"
  ...
  :ring {:handler todomvc-quiescent.serve/handler}
  ;; Note: it is not idiomatic to compile to, or serve from, the
  ;; project root but TodoMVC wants the index.html there, so we'll
  ;; adjust
  :clean-targets [:target-path :compile-path "generated" "main.js"]
  ...)

tjtolton12:04:07

@U3BALC2HH (friend studying this stuff with me) any guesses?

tjtolton12:04:16

I think it's referring to the line above it, the ring handler registration.. There's another line in the serve namespace:

(ns todomvc-quiescent.serve
  "Server for the todomvc app. Not necessary if demoing client-side
   pieces only."
  ...)

tjtolton12:04:48

I don't know what is normal, so I don't know what this project is doing to adapt to TodoMVC's requirements

hlolli12:04:15

what would be a good way to loop trough HTMLCollection (that gets returned by getElementByClassName) since its not seqable

[object HTMLCollection] is not ISeqable

hlolli12:04:01

solved it like this

(let [all-element-elements (-> (.getElementById js/document "x12-html")
                                              (.getElementsByClassName "element"))
         cnt-all-element-elements (.-length all-element-elements)]
          (doall
            (for [i (range cnt-all-element-elements)]
               (aget all-element-elements i))))

hlolli13:04:18

yes, I wonder why cljs ISeqable doesn't just extend to HTMLCollection by default?

pesterhazy13:04:42

Too special-casey?

hlolli13:04:55

I wonder if this answer is a fulfilling one, http://stackoverflow.com/a/23624517/3714556

thheller13:04:42

@hlolli (array-seq html-coll)

thheller13:04:54

do not extend any protocol on the native stuff, they are mutable collections and wreck havoc if you expect them to behave like clojure maps

hlolli14:04:52

so far I've never bumped into mutable/immutable collision, but I'd be interested to see one, for science.

istvan15:04:28

hey guys, i have never used javascript before, MutationObserver is the right things to fiddle with if i want to have all of the "events" from the DOM? is there a clojurescript api for this already?

roman01la15:04:16

@istvan no, this DOM API was deprecated

istvan15:04:43

roman01la i see, what is the standard way of listening to events nowadays?

roman01la15:04:18

@istvan it depends on what type of events you are talking about

istvan15:04:37

roman01la i would like to track click events for example

istvan15:04:53

lets start with that usecase

thheller16:04:00

@istvan you are looking at the wrong thing

thheller16:04:32

document.addEventListener("click", function(e) { ... }) to track all clicks on the page

thheller16:04:55

MutationObserver is meant as a way to observe changes to the DOM itself, ie. new nodes being added

thheller16:04:59

tracking clicks is not that

thheller16:04:40

(js/document.addEventListener "click" (fn [e] ...)) of course not that nasty JS πŸ˜‰

istvan16:04:56

thheller thank you

istvan16:04:22

may i track all of the clicks at once or i need to add EventListener to each one of them?

thheller16:04:35

depends on what you want to do really

istvan16:04:52

i am trying to instrument an app from the UX point of view

istvan16:04:14

need to know clicks and few other things (like scroll)

thheller16:04:22

if you attach to document you get all events in the page, if you attach it to a specific elements you only get clicks in that element

thheller16:04:29

events bubble up in the tree

thheller16:04:46

you can get the actual element that was clicked in the event

thheller16:04:46

so if you have 10 elements but all are contained in one other element you can do one event handler

istvan17:04:19

and you can attach do the document as well, getting all the events

thheller17:04:01

yes "click" is the event type

istvan17:04:24

(js/document.addEventListener "click" (fn [e] (js/console.log e)))

istvan17:04:35

wohoho, i can has events!

istvan17:04:41

thank you thheller !

istvan17:04:14

what is the best way of accessing properties of the events from clojurescript?

rgdelato17:04:52

I've been using (-> event .-target .-value)

anmonteiro17:04:12

FWIW you can use .. instead of ->

anmonteiro17:04:18

(.. event -target -value)

anmonteiro17:04:30

it’s a shortcut

thheller18:04:35

I prefer -> as .. only does native interop (-> event .-target .-value (some-fn)) doesn't work with ..

thheller18:04:11

but sometimes .. looks nicer πŸ˜‰

danielcompton18:04:27

@anmonteiro while you're here, is this safe: (js/console.log "test")? It works fine, but I sometimes wonder if I should be using proper dot syntax. (I only do this in dev)

anmonteiro18:04:58

@danielcompton I use that all the time

thheller18:04:27

@danielcompton I use that all the time as well

anmonteiro18:04:16

also just noticed something I should have deleted in that namespace πŸ™‚

thheller18:04:27

I think its fine for globals and would certainly be very upset should that ever be removed πŸ˜‰

mikerod18:04:46

My searches are not really finding anything to obvious so: are there any popular cljs libs out there for url encoding/decoding? client-side (in cljs, not clj)

darwin18:04:22

@mikerod google closure library has some utils for that

mikerod18:04:41

@darwin I was wondering if that was where I should go to for it

mikerod18:04:50

I was sort of surprised it was a hard thing to find via searches

shaun-mahood18:04:29

@mikerod: There's also https://github.com/lambdaisland/uri - I've not used it though but looks useful

darwin18:04:48

it is goog.Uri

mikerod18:04:50

thanks to both suggestions

rgdelato18:04:08

is there a good resource for things that are commonly used from the Google Closure library? All I've really found are these API docs: https://google.github.io/closure-library/api/index.html

dnolen18:04:07

@rgdelato there isn’t really beyond that

rgdelato18:04:29

Thanks. Sounds like maybe a good project for when I have more clj experience

rgdelato18:04:08

Also @mikerod, if all you need is to URL encode/decode and nothing fancier, there are methods built into the browser: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

mikerod18:04:12

@rgdelato thanks, yeah I thought probably it was just too basic

mikerod18:04:23

β€œbuilt-in” I mean

miguelb19:04:13

Is compiling UMD builds with webpack still the best way to get custom react components in a cljs app?

jevans19:04:39

Hi guys, just starting out learning reagent in clojurescript. I'm slightly confused when it comes to rendering html attributes which aren't key value pairs, e.g. for something like <a class="uk-alert-close" uk-close></a> how would I express this in the hiccip-esque syntax? [:a {:class "uk-alert-close" :uk-close}] Obviously doesn't work since the hash-map is invalid.

thheller19:04:36

@jevans :uk-close true

jevans19:04:19

@thheller doh

jevans19:04:37

cheers! (I tried empty string and nil, knew I was missing something)

rgdelato19:04:41

I think any non-empty string would also work? Back when XHTML was trying to be a thing, people would write stuff like <input checked="checked" /> whereas today we would just write <input checked />. (Note: This is beside the point. You should use true.)

pesterhazy19:04:56

I think react doesn't allow arbitrary attributes

pesterhazy19:04:25

:data-uk-close true will work though

john20:04:42

Is it possible to convert some string s such as: "#object[user$core$f \"function user$core$f(a,b){\nreturn (a + b);\n}\"]" into some object o where I can (.call o 1 2) to get 3? Outside of self-hosted mode?

noisesmith20:04:22

I forget the details, but I recall it gets much more complicated if there are multiple arities for the function

noisesmith20:04:30

it's not a simple built in feature

john20:04:53

that's right

thheller20:04:36

@john well you can (js/eval "function user$core$f(a,b){\nreturn (a + b);\n}") which will give you function in that case

thheller20:04:45

but the odds of that not working are extremely high

jatkins22:04:22

Hi everyone! I'm a recent Clojure(script) convert, and I'm trying to make a simple CLJS/Reagent project. Problem is, I want to have a different ns for each page. https://clojurescript.org/reference/compiler-options#modules modules seem to be the natural solution, but they require some optimizations to work correctly. On the other hand, figwheel requires no optimizations to be enabled. This leaves me at a loss for what to do. Keep in mind that I have very little experience with clojure or any build tools. (BTW, is this the kind of stuff clojurians is for?)

noisesmith22:04:50

you don't need modules in order to have an ns per page

noisesmith22:04:19

but what do you want these namespaces to do? is it that you want a different minimized js file for each page?

noisesmith22:04:34

(because this is not what namespaces in clojure are for)

jatkins22:04:13

It's because I have this at the end of each html file:```

jatkins22:04:20

<script src="/js/compiled/global-init.js" type="text/javascript"></script>
<script src="/js/compiled/out/page_name/page.js" type="text/javascript"></script>
<script type="text/javascript">goog.require("page-ns");</script>

jatkins22:04:59

I was thinking that it could compile all the relevant js files into just one big file, and just load that for each page. Is that how it works?

noisesmith22:04:16

this is how most of us do things, yes

noisesmith22:04:26

as I understand it, thanks to browser caching, it makes sense to put all your js in one file for the app, instead of having a different mix of smaller files per page

noisesmith22:04:38

but I'm not an expert, someone might have another suggestion

jatkins22:04:20

I suppose that would be an advantage, but I was/am getting tired of all the goog.require js that I was writing at the end of each file. Using :main in the project.clj (from how I understand it) takes care of all the boilerplate for you.

jatkins22:04:01

I was hoping that modules would work the same, but for multiple files.

noisesmith22:04:02

my approach would be to have a main that requires all your pages, and uses the location to decide which one to launch when it loads

noisesmith22:04:21

or query, or fragment, or however you organize it

jatkins22:04:30

Ah, so call into the js from the html page telling it which ui to setup?

noisesmith22:04:47

from the main ns

noisesmith22:04:12

that would be one way - but there's stuff your code could check without needing that to be called explicitly

noisesmith22:04:26

(eg. .-location of the browser etc.)

noisesmith22:04:09

since I think it's easier to not have varying inline js in various html files

jatkins22:04:44

Ok, thanks for the help!

shaun-mahood22:04:16

@jatkins: As a point of context, I've written plenty of CLJS and never had to write a single goog.require - so I think there's an easier way for you to get started. Check out the reagent and related clojurescript episodes at https://lambdaisland.com/episodes - they're very good and easy to follow, and there's a free trial so you can see if it's something that interests you further. There are also a lot of very helpful people in the #beginners channel that should be able to point you in other good directions as you run into more stumbling blocks.

jatkins22:04:28

Thanks for the tip! I'll be sure to check them out.