Fork me on GitHub
#clojurescript
<
2019-11-27
>
borkdude08:11:44

Is there a way to invoke a constructor in CLJS with an array instead of specifying the args separately? e.g.

(new* js/Error ["hello"])

borkdude08:11:48

without macros

borkdude08:11:56

apply seems to work, but not sure if I should be doing that

cjohansen08:11:36

apply works because Error can be called as a function and still behave as a constructor. this is true of many constructors in JavaScript, but not everyone

borkdude10:11:07

@christian767 can you give an example when this would not work? and what would be the proper solution in general?

cjohansen11:11:31

function Constructor(a, b, c) {
  if (!(this instanceof Constructor)) {
    return new Constructor(a, b, c);
  }

  // ...
}
@borkdude it will work with any constructor that does this ^^

cjohansen11:11:18

but not all of them do. for instance String(...) behaves differently from new String(...). With user provided constructors there's no way to tell other than checking the source.

borkdude12:11:57

oh ok, but is there is a way to invoke new from cljs with an array of args instead of single ones?

delaguardo12:11:58

new Error("message")

// is equivalent to

var errorInstance = Object.create(Error.prototype);
var error;
error = Error.call(errorInstance, "message")

borkdude12:11:59

thank you, but what if I get ["message"] instead of the args separately?

borkdude12:11:40

Error.apply maybe?

delaguardo12:11:40

apply should work, just tested it with Error

delaguardo12:11:06

error = Error.apply(errorInstance, ["message"])

borkdude12:11:58

cool, seems to work indeed:

(defn invoke-constructor #?(:clj [_ctx ^Class class args]
                            :cljs [_ctx class args])
  #?(:clj (Reflector/invokeConstructor class (object-array args))
     :cljs (let [args (into-array args)
                 obj (js/Object.create (.-prototype class))
                 obj (.apply class obj args)]
             obj)))

magra13:11:48

Hi, I am getting something very strange and wonder whether someone can hint to what is going on. The context is a fulcro app in the browser so it could be related to react or something. Here I map over notes, which works:

(dom/div (map ui-note (sort :note/id notes)))
ui-note is a factory for a react component. It works but it sorts differently in chrome and firefox. In firefox it ignores the sort, in chrome it sorts fine. but
(dom/div (map ui-note (sort #(> (:note/id %1) (:note/id %2)) notes)))
and
(dom/div (map ui-note (sort #(> (:note/id %1) (:note/id %2)) notes)))
work the as expected in both firefox and chrome. This behavior is there in development builds and production builds. I use shadow-cljs. It is not urgent, since it works with the lambda version but it confuses the heck out of me. Can anybody point me in a direction? I do not know how to google this. Thanks in advance!!

dpsutton13:11:36

Can you remove the dom related stuff and reproduce the bad sort in the repl with just data?

magra13:11:06

Good idea. I only use chrome for development. I will do that.

magra14:11:58

Its not the repl, but I changed it to (str (sort :note/id notes)) and they sort differently.

magra14:11:13

I will minimise to get a minimal reproducible case.

magra14:11:54

Ok. I have a webpage that renders

(str (sort :note/id '({:note/id 1} {:note/id 2}))).
Result on chromium 76.0.3809.132 freebsd and same on android:
({:note/id 1} {:note/id 2})
Result on firefox 70.0 on freebsd:
({:note/id 2} {:note/id 1})
Clojurescript Version as of deps.edn: 1.10.520

Roman Liutikov14:11:11

I can repro this as well

Roman Liutikov14:11:52

@magra you are using it wrong, sort takes comparator fn which takes two args

(str (sort #(compare (:note/id %1) (:note/id %2)) '({:note/id 1} {:note/id 2})))

Roman Liutikov14:11:34

I think in your case it’s undefined behavior

thheller14:11:01

you want to use sort-by not sort

βž• 4
magra14:11:06

ah!! that makes sense!! thank you! That explains why it works when I supply it πŸ˜‰

magra14:11:40

And thank you Thomas Heller, that is why I remembered it working.

Eliraz15:11:10

can someone clarify the difference between seq and seqable ?

dnolen15:11:36

seq is a seq, seqable means it can be coerced into a seq

mfikes16:11:34

To clarify, the above are really about seq? and seqable?

cjohansen16:11:15

Make sure we are thoroughly represented here, people: https://survey.stateofjs.com/ πŸ™‚

metehan17:11:17

Why CLJS calculates wrong?

Roman Liutikov17:11:31

you will the same result in jvm clojure, the problem is floating point numbers

wodin18:11:51

Here's a useful site about this https://floating-point-gui.de/

wodin19:11:05

Something like this decimal library might help: https://funcool.github.io/decimal/latest/

metehan20:11:14

thank you this library looks useful.

metehan17:11:24

I am trying to calculate VAT for users but CLJS makes up the answer

Edward Hughes21:11:14

Hey there, I was trying to use cemerick's fork of valip in a project, but when I try to start the server it throws Syntax error (IllegalAccessError) compiling at (valip/predicates.clj:1:1).read-string does not exist

Edward Hughes21:11:26

Do I have to include cljs on the server side somehow?

Edward Hughes21:11:12

Nevermind, figured out how .cljc works

Sidharth Sudarshan22:11:11

Hey guys, trying shadow for the first time (figwheel-main was my go to so far) .. starting up via cider M-x cider-jack-in-cljs gives me a clojure.lang.ExceptionInfo : missing instance { } error ... any clue what this is about?

Sidharth Sudarshan22:11:54

I'm guessing its looking for a shadow server. And lein should have started it but hasn't managed to?

Nima G23:11:10

Has anyone worked with Google Maps Javascript API (on client side) with shadow cljs? Assuming I load the library with my API key through the html page, how do I then create a Map object to configure it?

Sidharth Sudarshan23:11:20

solved: Run via shadow-cljs not lein in the cider popup. guessing it was a no-go on the build triggering server/start!. Suggest adding this to the user manual at https://shadow-cljs.github.io/docs/UsersGuide.html#cider

lilactown23:11:17

it is specified here: > CIDER will prompt you for the type of ClojureScript REPL: > > Select ClojureScript REPL type: > > Enter shadow.

Sidharth Sudarshan23:11:28

This refers to the second popup which asks to select between different REPLs - figwheel, nashorn, shadow etc This is taken care of in the .dir-locals.el file

Sidharth Sudarshan23:11:36

Let me get done with work, and ill remove the dir-locals and screenshot the 3 popups that come up in series. First popup: choose build tool : lein or shadow-cljs Second: choose REPL: figwheel, shadow, nashorn etc Third: choose shadow build: app, test etc

Sidharth Sudarshan00:11:40

Can share emacs/cider versions if it helps, and if this is not behaviour that is consistently observed.

dpsutton00:11:03

no that's the correct steps. it needs to know which executable to use to run, then what type of cljs repl you want, and then which build

Sidharth Sudarshan00:11:57

thanks @U11BV7MTK.. do you know how i can contrib to the docs, can't find it on the repo