Fork me on GitHub
#clojurescript
<
2017-04-20
>
oahner00:04:06

ohh, I think I see what's going on with my externs issue; it doesn't look like cljs parses the @extends jsdoc tags from gclosure's built-in externs

oahner00:04:51

I get warnings from *warn-on-infer* from methods that are defined on base classes of HTMLDocument, like EventTarget

danburton00:04:47

@anmonteiro hoping for v5 UUIDs

dnolen00:04:33

@oahner ah there you go, yeah file an issue

dnolen00:04:58

I didn’t consider inheritance

benny05:04:08

@nxqd how would I go about returning the result through a callback? feeling like quite the noob trying to figure out core async

benny05:04:35

my brain automatically tries to go to scala futures

jimmy05:04:08

ah you can do something like this:

(defn a [cb]
  (go ...
      (let [val ..]
       (when cb (cb val)))) 
;; usage
(a 
  (fn [val] 
   ;; you can use val here
  ))

jimmy05:04:59

This is not a great way to use core.async, but for simple use case this should work.

jntn05:04:53

May I ask why this not a great way to use core.async? I’m really new to clojure and are trying to learn 🙂

jimmy06:04:38

core async is really shine in complicated async operations. We use channel to pass data around. You can look at this example http://swannodette.github.io/2013/11/07/clojurescript-101 . However in the case above, we don't want to pass it anywhere, we just need to use it in current synchronous function ( which is into {} ... )

jntn06:04:47

I see, so its a bit overkill for simple usecases?

jimmy06:04:43

yeah. if you just want to use the returned value, just pass it through callback.

jntn06:04:44

Thank you for your explanation 🙂

jimmy06:04:58

np, glad to help

benny05:04:55

is there any way to just block the code on the go block and return the contents of the go block?

benny05:04:54

like can i do something like

(into {} :data (go (<! (get-item :data))))

jimmy05:04:12

no you cannot

benny05:04:14

I’m working with AsyncStorage in rn, maybe if i interacted with it directly would callbacks there be easier to block?

benny05:04:55

asked a different way, is there a way to emulate await in cljs?

benny05:04:08

nice, thanks!

benny05:04:17

looks like i’m still in the go block though eh?

benny05:04:37

I need to return the result unfortunately not the channel

jimmy05:04:10

as far as I can see, there are two ways you can get the value out of block: 1. using cb to return the value 2. send the value to another channel and catch it over there. ( it would be a little bit overkill in your case )

benny06:04:52

ok, thanks @nxqd i’ll try it out and see which makes more sense, appreciate the pointers!

jimmy06:04:17

np. glad to help

benny06:04:59

sweet thanks!

lxsameer09:04:11

hey guys, I'm looking for a good video to send to my friend to convince them to use clojurescript . Any suggestion ?

lxsameer09:04:58

thanks 🙂

plexus12:04:09

they might also appreciate this one. Not so much a marketing video but gives people an idea of how to do various JS things in ClojureScript https://lambdaisland.com/episodes/clojurescript-interop

jsa-aerial20:04:13

I found this https://www.youtube.com/watch?v=wq6ctyZBb0A#t=9.273001 to be both very useful and rather compelling

jeroenvandijk10:04:33

Did anyone build an exception notifier ala figwheel for runtime exceptions in cljs apps? I remember something vaguely, but cannot find it. I have something simple, but the devil is in the details, e.g. properly parsing the stacktrace

tomaas11:04:22

hi, in react.js one can pass a callback to setState funcion. Is there something similar in reagent with reset! some-atom val?

dominicm11:04:18

@tomaas what does the call back do? Is it called after state is updated?

plexus12:04:56

@tomaas maybe you're looking for add-watch?

dominicm13:04:37

@tomaas I think that having a callback to reset! doesn't make sense. Reading the docstring for swap! and reset! suggests that they don't return until applied. So if you do:

(reset! some-atom :val)
(println "guaranteed application: " @some-atom)

dominicm13:04:38

But of course, someone could modify the atom before your println. So you should probably do:

(let [new-val (reset! some-atom :val)]
  (println new-val) ;; => :foo
)

dominicm13:04:59

Though, I guess it's impossible in jsland. Still, code seems more correct with the let.

tomaas13:04:54

@dominic, thank you. Didn't know that reset! does not return until it's applied (if I understand correctly, setState in react's jsland is asyncronous, so reset! then returns when setState completes, right?). However, I don't understand the difference between your two snippets. Both of them execute in sequence as js in single thread.

dominicm13:04:31

> as js is single threaded Yeah, it potentially doesn't matter in js

dominicm13:04:04

@tomaas I think you may be confused about how reagent's ratom works. It isn't built upon react's state model, so it doesn't use setState under the surface afaik.

tech_hutch14:04:34

I'm using Atom with the linter-clojure plugin. In one of my ClojureScript files, it gives the error "No such namespace: js". Is there any way to fix this? Here's my code, if it matters: https://hastebin.com/ijuluvoduy.cljs (the error is on line 5)

dominicm14:04:38

@tech_hutch total aside: you don't need to wrap js/global in an atom 🙂

dominicm14:04:54

(I'm not sure it really makes sense)

tech_hutch14:04:59

I know that. I want to change that atom from another namespace.

tech_hutch14:04:33

The js/global is just a default 🙂

darwin15:04:40

goog/global would be a more portable way

darwin15:04:09

it works both in browser and node.js

tech_hutch15:04:47

So goog always contains all globals?

tech_hutch15:04:59

Oh wait, I see

tech_hutch15:04:06

goog.global contains all globals

darwin15:04:40

goog/global is an alias for js/window in browser contexts, and node.js global object in node.js

darwin15:04:18

read their sources, it simply captures this in global scope

darwin15:04:29

also rememeber that goog is a pseudo namespace in cljs, you don’t have to require it, it is always available

darwin15:04:37

similar to js pseudo namespace

tech_hutch15:04:55

I didn't know that

tech_hutch15:04:18

Do you have to import subnamespaces, like goog.object?

darwin15:04:36

only naked goog is pseudo AFAIK

darwin15:04:31

if I remember correctly, if you require it, it will still work, but you shouldn’t

tech_hutch15:04:38

How would I refer to require in node, then? (.-global goog)/require?

tech_hutch15:04:48

That doesn't look right

darwin15:04:57

this is an implementation detail, but base.js from google closure library must be always present, because cljs modules rely on it (and maybe some other infrastructure)

darwin15:04:25

I speak about (ns … (:require …))

darwin15:04:32

cljs requires not node.js requires

tech_hutch15:04:25

I know I meant

tech_hutch15:04:38

I was using js/require

tech_hutch15:04:02

How should I refer to it now?

darwin15:04:16

that’s fine

darwin15:04:18

my original reaction was to your usage of js/global, in this case goog/global would be better

darwin15:04:11

you wanted to have a var with a reference to the global object - js/global works only under node.js, there is no such thing in browser contexts

tech_hutch15:04:27

I got confused halfway through

tech_hutch15:04:59

But anyway, do you know any way to prevent the linter from throwing an error there?

tech_hutch15:04:28

I suppose requiring the js or goog namespace might fix it

darwin15:04:59

no idea, clojure linter is probably not aware of cljs pseudo namespaces

tech_hutch16:04:17

(:require js) does indeed get rid of the error.

urbank16:04:37

has anyone here used https://github.com/funcool/cats on the frontend? I'm interested in what context you used it

tech_hutch18:04:26

Adding (:require js) did indeed get rid of the linter error, but it made a compiler error.

tech_hutch18:04:45

I guess you can't require pseudo namespaces.

grav18:04:00

@urbank I’ve used it a bit for easily dealing with promises.

grav18:04:17

(javascript promises)

grav18:04:48

So I can do something like

(cats.core/alet [foo (async-fn1)
                 bar (async-fn2)
                 baz (async-fn3 bar)]
  {:foo foo :baz baz})

grav18:04:00

This will return a promise with a map with the resolved values of foo and bar. The cool thing is that in this case, async-fn1 and async-fn2 will be executed in parallel, whereas async-fn3 will be executed after async-fn2 since it relies on the resolved value of bar.

urbank18:04:39

@grav Hah, that's cool. I'll definitely use that

parentheian18:04:08

@grav that should be the front page example for their github as it totally answers "why?"

grav18:04:34

Haha, yeah 🙂 It doesn’t really answer the how-the-hell though. But it works 🙂

grav18:04:23

Btw. funcool’s promesa project also deserves a mention. https://github.com/funcool/promesa

grav19:04:03

Anyone using lein doo? I suddenly get ERROR: doo was not loaded from the compiled script.

spinningtopsofdoom19:04:39

That's from doo not getting compiled with your build. How are you building your project?

grav20:04:02

@spinningtopsofdoom I just run lein doo phantom test, I thought it built it?

romain20:04:05

@grav isn't phantom instead of phantomjs ?

grav20:04:25

Oh yes, correct

grav20:04:43

I do lein doo phantom test

grav20:04:04

I can run the doo example project successfully btw

romain20:04:11

Cool... But me I'm stuck. I try to add core.cljs in my core_test.cljs but phantom tells Invariant Violation: _registerComponent(...): Target container is not a DOM element.

spinningtopsofdoom20:04:24

lein doo does compile it. I was wondering with the build's compiler options are.

grav20:04:06

:compiler     {:output-to     "out/testable.js"
                               :target        :nodejs
                               :main          intro-lambda.doo-tests
                               :optimizations :simple}

grav20:04:26

Oh, now I got somewhere. I tried making it equal to the doo example. And removing :target :nodejs does the trick it seems

grav20:04:10

:target :nodejs probably doesn’t work with phantomjs

grav20:04:11

Make sense

spinningtopsofdoom20:04:15

Yep the problem was you were compiling to node which will break things

spinningtopsofdoom20:04:35

glad I could :rubber: 🦆

grav20:04:09

Yup, exactly 🙂

romain20:04:14

Any idea for my issue ?

spinningtopsofdoom20:04:25

Hmmm are you trying to register a react app on a DOM structure which doesn't exist (e.g. a bare phantomjs instance)?

romain20:04:29

I'm not sure to understand, but my core.cljs is a reagent app

spinningtopsofdoom20:04:13

For testing in phantomjs how are you loading DOM elements e.g.

<body>
  <div id="app"></app>
</body>

romain20:04:21

With reagent (r/render-component [game grid] (. js/document (getElementById "app")))

spinningtopsofdoom20:04:56

That doesn't create DOM elements it tells reagent where to load the component.

jsa-aerial20:04:15

lein-cljsbuild is a plugin to give lein cljsbuild awareness. Then there is cljsbuild which appears to go into the :dependencies vector. What is the latter anyway?

spinningtopsofdoom20:04:03

You'll need to create a DOM context for your reagent app to render onto.

romain20:04:37

@spinningtopsofdoom I just used some templates (lein new figwheel and lein new chestnut) but I didn't see the need to create a dom

spinningtopsofdoom20:04:21

You wouldn't if you were testing in the browser but with phantomjsyou'll need to create the DOM elements

romain20:04:17

Damn it's a "lot of work" to just launch tests in cider repl

hagmonk20:04:01

The goal in my case is to have the page load with everything it needs, i.e. not make a callback to the server. I'm thinking of serializing the data the page needs into JSON and shoving that in as an attribute in one of the hiccup tags.

hagmonk20:04:21

It feels kinda squiggly, if anyone has an alternative idea I'd appreciate hearing it 🙂

spinningtopsofdoom21:04:45

How about serializing everything to transit (https://github.com/cognitect/transit-cljs) and putting it in a top level var?

hagmonk21:04:13

how would I "inject" that transit into the top level var on the CLJS side?

noisesmith21:04:09

you would compile it into the page in a back-end template

noisesmith21:04:49

here’s how my prod app does it:

<script>
  window.environment_config = {{{environment}}};
</script>

noisesmith21:04:07

then the ring handler on the back end fills that in with a string, and the cljs parses it at runtime

john21:04:13

What's a good cpu heavy computation to test out concurrency on web workers? I'm trying to put together an example app to explain how to use this agent abstraction thing I'm working on.

john21:04:14

perhaps a large number of 250+ ms jobs that tend to drag on the main thread, that would be nice to offload on webworkers if it were more convenient...

noisesmith21:04:22

@john ackermann function

noisesmith21:04:31

or graph analysis of a large random graph

john21:04:29

I guess graph analysis would have more relevance to practical matters?

john21:04:43

Stuff people might do in the browser

noisesmith22:04:41

you could also do ray tracing if there’s a straightforward way to break up the parts into workers

noisesmith22:04:56

if you want something with visible demonstrable results and not just numbers to crunch

imdaveho22:04:48

hey all, just wondering as a newbie to clojure(script)...why such the heavy dependency on react and nothing else? Or is the idea that the NPM module support will allow clojurescript a better interop story for other frontend js frameworks?

noisesmith22:04:13

cljs itself doesn’t depend on react

imdaveho22:04:20

or is it a more enterprise-y response as in "why recreate the wheel" or "don't fix what isn't broken"

imdaveho22:04:31

sorry, I meant the front end libs

imdaveho22:04:57

the most popular are om, reagent, re-frame, etc...all the popular ones are all wrappers around react

noisesmith22:04:02

my impression is that folks like react because it allows controlling render using immutable data

noisesmith22:04:18

which is much more friendly to clojure dev style than other frontend frameworks I know of

imdaveho22:04:36

i guess it's also a matter of the js landscape at the moment

imdaveho22:04:44

but does cljs prevent you from using other frameworks?

imdaveho22:04:49

like vue, angular, mithril?

noisesmith22:04:51

absolutely not

imdaveho22:04:23

and there is no impact either on the closure compiler? since it's just compiling down your cljs, right?

noisesmith22:04:06

exactly - I’ve done cljs without react. But react and cljs fit nicely because they have some design decisions that align nicely.

imdaveho22:04:43

I'm also assuming you lose isomorphism without the native cljs wrappers for react...ie if you just use cljs interop with a js framework

imdaveho22:04:13

wait...that might be wrong...is there interop between clojure in the backend and clojurescript on the front?

noisesmith22:04:57

no, all interop is with the host

noisesmith22:04:52

there’s cljc files that can have code that runs on both clj and cljs - but I wouldn’t expect any code using react to be shared

mikethompson23:04:13

@imdaveho React is "functional" in nature, so it is an excellent match for clojurescript which explains its popularity.

mikethompson23:04:53

So, yes, you could absolutely "wrap" Angular and Vue ... there's a good interop story between ClojureScript and js ... but the result would not be as pleasing to clojure sensibilities