Fork me on GitHub
#sci
<
2022-04-16
>
lilactown02:04:48

(defn user-class
  []
  #js {:a (fn [x]) :b (fn [y])})
@hoertlehner JS classes are fundamentally functions that return objects. there might still be some caveats, but try that and see if it works

awb9903:04:49

Thanks @lilactown unfortunately it does not work. I tried that earlier. But now that you said it .. perhaps it only does not work because the function is not exported to js by sci.

borkdude04:04:30

SCI function are just normal JS functions unless you attach metadata to them

borkdude04:04:08

Perhaps you can use js/eval to construct the constructor or js/Reflect

borkdude04:04:43

Note that hyphens do not work in names in JS. Please be as exact as you possible can and make an exact repro of the problem which we can try locally.

borkdude04:04:04

You could maybe also set the constructor property manually using interop

borkdude08:04:33

I found some information here: https://stackoverflow.com/questions/3871731/dynamic-object-construction-in-javascript Looks quite complicated. Is it possible to define the constructor in JS and then bind that to your SCI options?

borkdude08:04:48

Hmm, wait, this seems to work, like @lilactown said:

user=> (defn foo [] #js {:a (fn [] :hello)})
#'user/foo
user=> (new foo)
#js {:a #object[Function]}

borkdude08:04:58

> perhaps it only does not work because the function is not exported to js by sci. @hoertlehner you can "export" this function by setting it on the global object:

user=> (set! (.-foo js/globalThis) foo)
nil
user=> js/foo
#object[Function]

awb9921:04:55

@U04V15CAJ. I did execute your example above in sci in the browser. Then I enter the following into the devtools in the browser in Javascript:

var x = new foo()
x.a

awb9921:04:30

{"meta": null,
  "Ba": 2,
  "qa": [
    {
      "fd": null,
      "name": "line",
      "za": "line",
      "_hash": 212345235,
      "la": 2153775105,
      "sa": 4096
    },
    1,
    {
      "fd": null,
      "name": "column",
      "za": "column",
      "_hash": 2078222095,
      "la": 2153775105,
      "sa": 4096
    },
    22
  ],
  "ea": null,
  "la": 16647951,
  "sa": 139268
}

awb9921:04:23

When I try to call x.a () I get the following error: Uncaught TypeError: x.a is not a function

borkdude21:04:06

@hoertlehner This is a Clojure hashmap being printed. Can you make a repro like this in #nbb for example? Which is also a SCI-based Clojure env on JS.

Welcome to nbb v0.3.7!
user=> (defn foo [] #js {:a 1})
#'user/foo
user=> (set! (.-foo js/globalThis) foo))
nil
user=> (js/eval "new foo().a")
1

borkdude21:04:15

It could also be that you're returning a function which contains metadata. Which version of SCI are you using btw?

borkdude21:04:59

user=> (defn foo [] #js {:a (fn [] "hello")})
#'user/foo
user=> (set! (.-foo js/globalThis) foo))
nil
user=> (js/eval "new foo().a()")
"hello"

awb9921:04:10

This is the repro:

(defn afn [] "hello")
(defn foo [] #js {:a afn})
(set! (.-foo js/globalThis) foo)
(js/eval "new foo().a")

awb9921:04:19

The output of this is "afn"

borkdude21:04:14

user=> (js/eval "new foo().a")
#object[Function]
user=> (js/eval "new foo().a()")
"hello"

awb9921:04:21

But since I use this from javascript, it should return a js function

awb9921:04:23

borkdude/sci {:mvn/version "0.2.7"}

borkdude21:04:49

you might want to try 0.3.4 or so

borkdude21:04:03

since I can't repro this with the newest SCI

awb9921:04:15

ok. great.

awb9921:04:03

I did believe that I integrated sci quite recently (a few months ago). You are pushing out new versions at an amazing speed!

borkdude21:04:31

Note that newer versions of SCI are available under org.babashka/sci , no longer under borkdude/sci

borkdude21:04:45

@hoertlehner Indeed, with 0.2.7 I was able to reproduce your issue, but not with 0.3.4

awb9921:04:52

Thanks a lot!