Fork me on GitHub
#clojurescript
<
2017-11-14
>
OliverM00:11:34

How do you invoke an es6 static class method from ClojureScript?

rgdelato00:11:59

@oliver.mooney Is this what you're asking?

class Foo {
  static bar() {
    console.log("baz");
  }
}

rgdelato00:11:13

(.bar js/Foo) ;; logs "baz"

lovuikeng07:11:17

"Everybody using reagent was mind blowing, you write functions, and functions make the UI, it's a beautiful world!..It's no wonder that it's just blew up. within 4 months, everyone in ClojureScript was using react we're adopting react before JavaScript was adopting react" https://soundcloud.com/defn-771544745/26-with-david-nolen-aka-swannodette

danielpquinn07:11:12

I have a cljs fn that takes a javascript object instance as an argument. I want to call a method on the instance from cljs, but advanced optimizations shortens the method name

danielpquinn07:11:44

(fn [my-instance] (.sayHello my-instance))

danielpquinn07:11:11

Is there a simple way to tell closure compiler not to shorten sayHello?

danielpquinn07:11:20

Right, but how do I tell the compiler what my-instance is in this case?

danielpquinn07:11:25

I feel like I’m missing something obvious

thheller07:11:23

(fn [^js my-instance] (.sayHello my-instance))

vemv10:11:28

I love this kind of assertion from Ruby Rspec: expect { some_side_effectful_code }.to_change { some_variable }.from(:foo).to(:bar) That's a stronger assertion than the more typical

some_side_effectful_code

expect(some_variable).to equal(:bar)

Because one asserts cause-effect relationship between excercised code and expected values. At work we use cljs.test. What's the cheapest (i.e no framework swap) thing we can bring for getting this kind of assertion?

tatut10:11:58

what does it mean to “change a variable” in this context?

vemv11:11:05

@tatut better worded: the return value of a piece of code

vemv11:11:11

was thinking, this assertion would be trivial to implement api:

(expect some-side-effectful-fn
        :to-change get-counter
        :from 1
        :to 1)

vemv11:11:44

impl would simply invoke cljs.test (is (= ...)) which you absolutely can do programatically

tatut12:11:13

so expands to something like (let [old-value (get-counter)] (some-side-effectful-fn) (let [new-value (get-counter)] (is (= old-value 1)) (is (= new-value 1))) ?

tatut12:11:02

I think the plain cljs test version using let is pretty simple, if you don’t need it often

sandbags13:11:20

anyone about who uses the Klang library?

sandbags13:11:56

started seeing “Uncaught ReferenceError: React is not defined” errors that seem to be coming out of the Klang initialisation code.

sandbags13:11:24

not sure what i might have done that could trigger that

vemv13:11:03

@tatut yeah exactly

vemv13:11:26

we had be using this pattern (or similar) with cljs.test from time to time - so worth abstracting away in our case!

rauh13:11:32

@sandbags Do you have react loaded before klang?

sandbags13:11:35

@rauh i assume so, i’m not really clear how i would affect that (since this was working)

sandbags13:11:48

sorry, useful context, i am using re-frame

rauh13:11:29

So it was working before, but now not?

rauh13:11:36

In a dev environment?

sandbags13:11:06

i’ve been using it for months, not seen this before

rauh13:11:01

Did you upgrade re-frame or reagent? Maybe they're using npm nowadays and don't define the global react anymore?

sandbags13:11:25

no, not upgraded either

sandbags13:11:31

the google dependency code seems to be referencing React via cljsjs at least as far as i can tell. I’m not sure how the dependency order is calculated or why anything I might do would change this.

sandbags13:11:59

i mean, React is definitely there or none of the re-frame code would work

sandbags13:11:19

grr… pulling all the calls to info! would be a pita

rauh13:11:24

@sandbags I should probably change the code of klang to not require React upon loading the namespace and lazy initing everyting. I'll do it real quick

sandbags13:11:03

@rauh ah, sorry i didn’t put two and two together … so first of all, thank you for Klang!

sandbags13:11:38

i was in the middle of writing a Github issue … is it worth continuing with that?

rauh13:11:44

@sandbags Not unless you have info about why React isn't defined. I completely leave that up to the user.

rauh13:11:03

But I agree that I shouldn't make calls to js/React unless you actually show the overlay.

rauh13:11:14

So later on in time...

sandbags13:11:10

I have no insight whatsoever into why React isn’t defined 🙂

sandbags14:11:21

@rauh the error is different now, there is less to the stack trace but it’s still there… 🙁

sandbags14:11:59

@rauh klang.core:50 (def h js/React.createElement) is what’s causing it now

sandbags14:11:20

it’s really weird the way this has popped up

sandbags14:11:51

besides at the point where I :require [klang.core] i should have thought React would be available

ajs15:11:23

Also listen to Tony Kay's episode, where he discusses the other side of Reagent. Good to know the pros and cons. "Reagent doesn't lend itself to simplicity."

pesterhazy15:11:21

@ajs, reagent as opposed to which alternative?

ajs16:11:04

@pesterhazy he was comparing it to two other libraries, Om Next and Rum

ajs16:11:17

mostly Om Next though

mfikes16:11:32

@jeaye There is now a patch in https://dev.clojure.org/jira/browse/CLJS-2397 which, if things went that way, would have at least saved you some time by warning about instrumenting multi-arity functions.

qqq16:11:23

I'm running boot cljs and getting the following error:

boot cljs
Writing main.cljs.edn...
Compiling ClojureScript...
• main.js
                                       java.lang.Thread.run                  Thread.java:  748
         java.util.concurrent.ThreadPoolExecutor$Worker.run      ThreadPoolExecutor.java:  624
          java.util.concurrent.ThreadPoolExecutor.runWorker      ThreadPoolExecutor.java: 1149
                        java.util.concurrent.FutureTask.run              FutureTask.java:  266
                                                        ...                                   
                        clojure.core/binding-conveyor-fn/fn                     core.clj: 2027
                              adzerk.boot-cljs/compile-1/fn                boot_cljs.clj:  160
                                   adzerk.boot-cljs/compile                boot_cljs.clj:   72
                                          boot.pod/call-in*                      pod.clj:  413
                                                        ...                                   
org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke  ClojureRuntimeShimImpl.java:  102
org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke  ClojureRuntimeShimImpl.java:  109
                                                        ...                                   
                                          boot.pod/call-in*                      pod.clj:  410
                                      boot.pod/eval-fn-call                      pod.clj:  359
                                         clojure.core/apply                     core.clj:  657
                                                        ...                                   
                         adzerk.boot-cljs.impl/compile-cljs                     impl.clj:  156
                            adzerk.boot-cljs.impl/dep-order                     impl.clj:   36
               adzerk.boot-cljs.impl/cljs-depdendency-graph                     impl.clj:   29
                                        clojure.core/reduce                     core.clj: 6753
                                clojure.core.protocols/fn/G                protocols.clj:   13
                                  clojure.core.protocols/fn                protocols.clj:   75
                         clojure.core.protocols/iter-reduce                protocols.clj:   49
            adzerk.boot-cljs.impl/cljs-depdendency-graph/fn                     impl.clj:   30
                      adzerk.boot-cljs.impl/ns-dependencies                     impl.clj:   23
                                  cljs.analyzer.api/find-ns                     api.cljc:  163
  java.lang.AssertionError: Assert failed: (symbol? sym)
clojure.lang.ExceptionInfo: Assert failed: (symbol? sym)
    line: 104
I'm 99% certain that this is NOT an assertion I wrote, but some assertion somewhere in cljs/boot code. Is there a way to get the name of the file it was processing when this error occured ?

jeaye17:11:19

@mfikes Yep, I've been following. Thanks for the patch. Either support for this or a diagnostic would've solved my problem, so what you've done is good by me! Thanks again.

vemv18:11:39

Someone around here might know! (even if not, this might interest you)

roklenarcic19:11:51

I'll ask here: I've been using goog.i18n libs to format dates. The issue I'm having is that it seems to be forcing american style dates, even when I have English (UK) at my most preferred language in chrome and the header my chrome produces is Accept-Language: en-GB,en-US;q=0.8,en;q=0.6

zalky19:11:00

@roklenarcic, unfortunately, this may not answer your question, but just in case: as a workaround, you might consider using the cljs-time lib. It provides a lot of flexibility in formatting dates, and lot of out-of-the-box formatters too.

roklenarcic19:11:46

thanks will check it out

roklenarcic19:11:22

So the british locale should be preferred, but it isn't?

zalky19:11:34

Hi all. Experimenting with an integrated clj/cljs/js environment. Basic story I'm trying to implement is to get code written in js to easily consume cljs namespaces. To that end I've been using the techniques described here https://clojurescript.org/reference/dependencies under the section "Google Closure Compiler Compatible Code". This leads to a very simple example:

goog.provide('js.lib');
goog.require('cljs.lib');

js.lib.debugMessage = () => {
  console.log(cljs.lib.some_cljs_var);
};
I have two basic questions: 1. Is there any other way besides marking a var as ^:export in cljs to properly resolve a cljs some_cljs_var in js? It's a little annoying to have to re-define a js api with ^:export and underscores. 2. What is the recommended way to consume cljs objects in js? Like if I have a configuration map stored as a var in cljs, and want to use that in js? I know about clj->js but not quite sure how to use that in js. Or maybe there's another approach altogether?

roklenarcic20:11:52

Was the way macros are done in cljs changed recently? I remember hearing something about that?

thheller20:11:17

@roklenarcic no, nothing changed recently.

thheller20:11:34

@zalky what are you trying to do exactly? dont need the ^:export. not sure what you mean by the “underscores”, JS can’t have - in names so its converted to _ in JS always.

darwin20:11:07

I think one way around ^:export would be to manually set! interesting functions on some global object, for example js/window and at that point you have a chance to rename them to javascript convetions

mfikes20:11:34

@zalky When using ^:export you shouldn’t have to rename in order to introduce underscores. See https://clojurescript.org/reference/advanced-compilation#access-from-javascript

zalky20:11:54

@thheller: I'm trying to consume cljs functions and vars from within js code. I'm experimenting with a build that would allow js developers to participate in a project, mostly working on view related code. My minimal example above shows the basics of the approach I'm trying. As far as I know, in order to guarantee the name of the compiled cljs var (ie: once it's compiled to js) is to use ^:export. And because, exactly as you say, js can't have -s, they need to be replaced, conventionally with _, but I suppose you could also use camelcase. To be honest, the ^:export is only a minor annoyance. What I'm much more interested in is what the best approach is for passing data back and forth between the cljs and js.

mfikes20:11:30

@zalky I would go with ^:export and go with the convention that all of the arguments and return types are just JavaScript objects (and force the ClojureScript side to do the JavaScript interop.)

zalky20:11:19

@mfikes: thanks! That's very helpful. What about if you have some cljs object defined in a var, (like let's say an ontology map or something) that is also being used by the cljs side?

zalky20:11:39

I suppose i could just re-def the var.

mfikes20:11:41

Perhaps use clj->js before returning it to JavaScript

mfikes20:11:26

Otherwise if it needs to be simultaneously accessed from both sides, I’d keep it as JavaScript if possible.

darwin20:11:23

I would do the same as @mfikes, but instead of ^:export I would write a macro which would walk interesting namespaces and emit a js object which would act as a namespace for collected functions, in that namespace I would camelCase the names for convenience of my js devs, I would set that object as global, for example to window.myAPI

zalky20:11:41

Do you think that doing something like:

(def cljs-map
  {:this "that"})

(def ^:export js-map
  (clj->js cljs-map))

zalky20:11:25

Would be a bad approach? On the one hand, it's manual work, on the other, it explicitly enumerates the js api.

davertron21:11:02

Hi, this seems like a simple question but I’m having a hard time finding an answer…Can I use a normal clojure library in clojurescript? For example, I would like to use reduce-fsm (https://github.com/cdorrat/reduce-fsm) in my current project

zalky15:11:10

@U0HF3QKAM: Unfortunately I don't think there is. However, there is a great FSM library called automat that works in both clj and cljs. https://github.com/ztellman/automat

davertron15:11:52

That’s actually the first one I came across, but the repo is “archived”. I wasn’t sure if that meant it was basically abandoned, or if it was just “done” 🙂. I’ll take a look though if it works in cljs. Thanks for the heads-up!

phronmophobic21:11:09

for reduce-fsm specifically, it looks like a lot of the usage is via macros, which you can use from javascript clojurescript

phronmophobic21:11:58

but in general, unless the library is using cljc files, it won’t be available to clojurescript and clojure

gklijs10:11:54

I just would like to add that in some cases like core.async not all functions from clojure are also available in clojurescript. And for some libaries there are clojurescript alternatices with the same fuctions. Like spec. Which you might use in a cljc file like: (:require [#?(:clj clojure.spec.alpha :cljs cljs.spec.alpha :default clojure.spec.alpha) :as s])