Fork me on GitHub
#clojurescript
<
2017-10-04
>
genekim02:10:00

@bhauman Very cool! Was actually trying last week trying to get devcards to work with a re-frame application, but gave up and doing it in doo/karma/cljs.test instead. Is there an example app that works with React that I can try copying from? Thanks again for all your great work!

bhauman02:10:18

@genekim there is the devcards lein template lein devcards my-project.. but I don't recommend devcards as your primary test suite. I do recommend it for building a library of components that you can work on in isolation.

johanmynhardt07:10:44

Hmm. It seems to be a controversial subject. Maybe I'm just googling using the wrong terms. I want to create JS libraries/utilities but code them in ClojureScript. Is it just a bad idea?

johanmynhardt07:10:25

The scenario is that I have a big JS-based project, but want to start doing some parts in CLJS

thheller07:10:33

@johanmynhardt depends. are they going to be used in node or the browser?

johanmynhardt07:10:10

It's a PolymerJS project that I want to use it in.

thheller07:10:30

lets you use CLJS with JS tooling

johanmynhardt07:10:42

ooh, I'm going to have a look, thank you @thheller 🙂

genekim08:10:12

Thanks again @bhauman. FWIW, it was your clojureconj west talk on figwheel that made me jump in and try ClojureScript. Watching the video made me laugh uproariously, and later, cry as I went back to doing things the old way with TypeScript,, React and Gruntfiles. :) Keep up all the amazing work!

hkjels10:10:37

I have dev, stage & prod builds in leiningen and each of them declares some goog.VARS, but prod ends up overriding stage. Any idea why that can happen?

hkjels10:10:49

I mean, when I do cljsbuild once stage I get the value from the prod block

Petrus Theron13:10:43

Having a hard time getting Cljs to recover from an error. If I do anything invalid like refer to an undefined symbol, boot-reload will load in the corrected script, but trying to render anything throws `Cannot read property ‘getNativeNode’ of null” Any idea how to get Cljs to recover from exceptions?

rauh13:10:24

@petrus IIRC: That's Reacts error. Re-mount your entire react app upon reload and it should work.

Petrus Theron13:10:42

(defn mount []
  (prn "mounting")
  (reagent/render-component [parent-component (:app @!system)]
                            (.getElementById js/document "app")))
I can see “mounting” printed on a change

Petrus Theron13:10:46

What can I do until Reagent supports React 16 as per https://github.com/reagent-project/reagent/pull/308? Wrap the render-component call in a try-catch?

pesterhazy13:10:29

@petrus, to elaborate on what @rauh said, the problem (if it is your problme) occurs when an exception is thrown during a render fn

pesterhazy13:10:55

React normally doesn't recover from exceptions in render functions

mfikes13:10:29

@hkjels by goog.VARS, do you mean :closure-defines? I don't have a ton of experience with that feature, but I wonder if you might run into what you describe if you don't clean between switching builds

hkjels13:10:59

@mfikes closure-defines yes. However I run it using lein do clean, cljsbuild once stage

mfikes13:10:19

@hkjels Is the separation at the project.clj (top-level) :profiles level, or at the :builds level (inside of :cljsbuild)

hkjels13:10:52

at the :builds level

mfikes13:10:50

That might be the problem. (I have my builds separated as :profiles) Curious: Do you have different :output-dir settings for each?

hkjels13:10:51

yeah, but output-to are different

hkjels13:10:02

no, sorry, the same

hkjels13:10:30

so output-dir and asset-path are all different

mfikes13:10:46

I'm not an expert on this, but my setup is the template from re-natal https://github.com/drapanjanas/re-natal/blob/master/resources/project.clj

mfikes13:10:34

re-natal, for example uses :builds to produce one each for iOS, Android, for example, for a given :dev or :prod profile

mfikes13:10:23

Hrm... well, I'm only speculating at what proper behavior should be here is. I would dig into lein or cljsbuild's code to see how things are merged together

hkjels13:10:17

yeah, I’ll get back at it this evening. Right now I have to pick up some kids 🙂 Thank you!

hkjels13:10:21

for your time

mfikes13:10:25

no prob 🙂

rauh13:10:03

@petrus I don't do reagent, but rum. But try to call unmount-comp on reagent before mounting. That's what I do and it properly recovers

rauh13:10:05

Yes, try that.

Petrus Theron13:10:27

Does not seem to work (in mount):

(let [elem (.getElementById js/document "app")]
    (reagent/unmount-component-at-node elem)
    (reagent/render-component [parent-component (:app @!system)] elem))

rauh13:10:52

Still the same error? I use v16 and they also changed the defautl behavior (see: https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html#new-behavior-for-uncaught-errors ). Can you upgrade to 16?

Petrus Theron14:10:50

how do I upgrade to React 16 without problems? This doesn’t seem to cut it:

[reagent "0.6.0" :exclusions [cljsjs/react cljsjs/react-dom]]
[cljsjs/react "16.0.0-0"]
[cljsjs/react-dom "16.0.0-0"]
I get TypeError: reagent.impl.util.react.createClass is not a function

thheller13:10:51

reminder: please vote and share. trying to get some numbers on required JS interop work. https://twitter.com/thheller/status/914427680690405378

juhoteperi14:10:58

@petrus React 16 doesn't have createClass, you'll need to use Reagent 0.7+ and add create-react-class dep

paytonrules15:10:11

Oh @genekim your snippet of plugins says “lein-doo 0.1.7” (which matches the screencast but you’re downloading “lein-doo 0.1.8"

paytonrules15:10:33

Looks like you have some kind of mismatch. doo 0.1.8 was just released - a couple days ago it looks like based on github - and if you make sure your project.clj is referencing 0.1.8 I think you might be in luck. I just set it up on an existing project a few minutes ago and it worked the first try. Earlier I was having problems with 0.1.7, so it may be an error in that version.

psdp15:10:35

Hi, noob question: anyone know how to get puppeteer working for node cljs? I wanted to use it with promesa Async/Await Syntax. Doesn't seem to work, why?

(ns app.main
  (:require [promesa.async-cljs :refer-macros [async]]
            [promesa.core :as p]))
            
(def puppeteer (js/require "puppeteer"))

(async
 (let [browser (p/await (.launch puppeteer))]
   (js/console.log (p/await (.version browser)))))
Unhandled rejection Error: kill ESRCH                                                                                                                 
    at exports._errnoException (util.js:1022:11)                                                                                                      
    at process.kill (internal/process.js:173:13)                                                                                                      
    at killChrome (/home/cljs-test/target/node_modules/puppeteer/lib/Launcher.js:122:19)
    at Function.launch (/home/cljs-test/target/node_modules/puppeteer/lib/Launcher.js:108:7)
...

lilactown16:10:24

how do I get npm-deps to install?

lilactown16:10:54

i'm starting figwheel + cljs REPL from EMACS/CIDER and I get

Failed to compile "target/js/compiled/pickle.js" in 3.218 seconds.
----  Could not Analyze  src/pickle/sources.cljs  ----

  No such namespace: whatwg-fetch, could not locate whatwg_fetch.cljs, whatwg_fetch.cljc, or JavaScript source providing "whatwg-fetch" 

lilactown16:10:23

in my project.clj:

:cljsbuild {
    :builds [{:id "dev"
              :source-paths ["src"]
              :figwheel true
              :compiler {
                :main pickle.core
                :asset-path "target/js/compiled/dev"
                :output-to "target/js/compiled/pickle.js"
                :output-dir "target/js/compiled/dev"
                :target :nodejs
                :optimizations :none
                :source-map-timestamp true
                :npm-deps {:whatwg-fetch "2.0.3"}}}
             {:id "prod"
              :source-paths ["src"]
              :compiler {
                :output-to "index.js"
                :output-dir "target/js/compiled/prod"
                :target :nodejs
                :optimizations :simple
                :npm-deps {:whatwg-fetch "2.0.3"}}}]}

lilactown17:10:04

that worked 😓 thanks @U61HA86AG!

dpsutton17:10:12

does anyone know of any queiscent apps out there where i could read the source? The todo-mvc quieiscent app is quite strange it seems. making a channel for each property of state and having to create its own request render function. seems overly complicated unless that's just what you're supposed to do

dhirensr17:10:49

has anyone use react sidebar using reagent?

richiardiandrea18:10:15

maybe a stupid question, is *ns* bound at runtime or compile time for Clojurescript? Can I use it in my logs?

richiardiandrea18:10:19

uhm, self-answer...it is runtime, but probably not if I am using it inside a macro

noisesmith18:10:00

*ns* always exists, but the current value is determined by the context of the call, not the context of the definition (dynamic var)

noisesmith18:10:27

also I wouldn’t expect *ns* to be useful in cljs, outside of macros

richiardiandrea18:10:08

so what I would like to do is (defonce log (.child l/parent-logger #js {:ns *ns*})) at the top of my file, but I don't think this works

noisesmith18:10:41

@richiardiandrea that would end up using the *ns* of the code that invoked the macro

richiardiandrea18:10:59

yeah I am afraid so

richiardiandrea18:10:37

and macros in cljs happen in another world entirely 😉

noisesmith18:10:55

right, and cljs doesn’t really have useful namespaces the way clj does

noisesmith19:10:16

(at runtime - they arguably exist in some form but it’s a trickier story)

richiardiandrea19:10:17

in lumo they exists in form of compiler state at the repl...but actual compilation is another kettle of fish

richiardiandrea19:10:00

probably I could create a macro that expands to a read to the compiler state?

noisesmith19:10:56

@richiardiandrea what are you trying to do?

noisesmith19:10:12

like big picture, do you just want the code to know what namespace the calling code was in?

richiardiandrea19:10:13

replace the *ns* above with the actual namespace name

noisesmith19:10:01

wouldn’t it be easier to a) make it a macro, then the caller of the macro would fill in the *ns* properly, or b) make the ns an explicit argument?

richiardiandrea19:10:39

for sure it is a macro, but that info only exists at compile time probably

noisesmith19:10:13

right but if *ns* is part of the macro expansion, and the macro is called in ns foo, then *ns* will expand to foo

richiardiandrea19:10:15

I am trying smth out 😉

richiardiandrea19:10:02

so basically I don't see in the compiler a way to say "I am compiling X namespace", which is basically what I want to extract, I will dig more and just hardcode the namespace as string now in there

thheller19:10:36

*ns* says that in macros

noisesmith19:10:42

@richiardiandrea what about (defmacro my-ns [] *ns*)

noisesmith19:10:52

that would work in functions even

thheller19:10:56

at runtime there is no such thing as a current ns

richiardiandrea19:10:09

no it does not work, I have tried

richiardiandrea19:10:31

there might be some lumo problem however, not sure

noisesmith19:10:38

at the time of the macro’s expansion *ns* should have the value of the one using the macro…

richiardiandrea19:10:14

I have:

(defmacro current-ns
  []
  *ns*)
😄

noisesmith19:10:40

(ins)cljs.user=> (defmacro my-ns [] *ns*)
true
(ins)cljs.user=> (ns foo.bar)
nil
(ins)foo.bar=> (.log js/console (cljs.user/my-ns))
{ obj: {},
  name:
   { ns: null,
     name: 'foo.bar',
     str: 'foo.bar',
     _hash: 1702737123,
     _meta:
      { meta: null,
        cnt: 5,
        arr: [Object],
        __hash: null,
        'cljs$lang$protocol_mask$partition0$': 16647951,
        'cljs$lang$protocol_mask$partition1$': 8196 },
     'cljs$lang$protocol_mask$partition0$': 2154168321,
     'cljs$lang$protocol_mask$partition1$': 4096 },
  'cljs$lang$protocol_mask$partition0$': 6291456,
  'cljs$lang$protocol_mask$partition1$': 0 }
nil

richiardiandrea19:10:56

oh ok, well it works for sure in the repl

richiardiandrea19:10:24

sorry, I did not specify that I am compiling down to JS

richiardiandrea19:10:57

I am trying with vanilla cljs now just to see if it is a lumo issue

mfikes19:10:30

If you have a Var in your namespace, say x, then perhaps you can statically get what you want with an expression like (namespace (.-sym (var x)))

richiardiandrea19:10:05

oh, nice hack 😉

mfikes19:10:25

If you don't want to depend on .-sym you could perhaps do something more complicated like (let [s (pr-str (var x))] (subs s 2 (- (count s) 2)))

richiardiandrea19:10:31

well no I think I am fine with that

mfikes19:10:15

I wonder, though if (.-name *ns*) works

richiardiandrea19:10:33

will try for completeness

mfikes19:10:51

Or just (str *ns*)

richiardiandrea19:10:47

compiles to: processor.log = logging.parent_logger.child(({"ns": cljs.core._STAR_ns_STAR_.name})); so it should work?

richiardiandrea19:10:07

or maybe not just a sec

mfikes19:10:40

Oh, right. You want to grab it statically at compile time.

richiardiandrea19:10:49

yep at compile time

rauh19:10:47

Compiling with the JVM?

rauh19:10:05

Why not (defmacro my-ns [] (str (ns-name *ns*)))?

richiardiandrea19:10:44

compilation was failing but there might be a lumo problem there

richiardiandrea19:10:08

@rauh actually your version works!

richiardiandrea19:10:32

so only (defmacro current-ns [] *ns*) fails the compilation, we where on the right path @noisesmith

richiardiandrea19:10:42

thanks both for your suggestions

richiardiandrea19:10:54

actually all three 😉

mfikes19:10:35

Yeah, I like @rauh's suggestion

mfikes19:10:03

ns-name is supposedly only for bootstrap

richiardiandrea19:10:37

very useful, btw also (str *ns*) works

mfikes19:10:02

Maybe you could throw (str *ns*) in a macro, and that would grab it statically

rnagpal21:10:08

I am facing problem in writing macro

rnagpal21:10:16

(defmacro loader
  [component arguments sub]
  `(let [show-loading? (reagent/atom false)]
     (reagent/create-class
       {:component-did-mount
        (fn component-did-mount [_]
          (when-not @show-loading?
            (js/setTimeout #(when-not @sub
                              (reset! show-loading? true))
                           500)))
        :reagent-render
        (fn [] ~component)})))


(println (loader [:div [:div]] [] [1 2]))

rnagpal21:10:09

(cljs.core/let
  [test.common.loading/show-loading? (reagent.core/atom false)]
  (reagent.core/create-class
    {:component-did-mount
     (cljs.core/fn
       test.common.loading/component-did-mount
       [test.common.loading/_]
       (cljs.core/when-not
         @test.common.loading/show-loading?
         (js/setTimeout
           (fn*
             []
             (cljs.core/when-not
               @test.common.loading/sub
               (cljs.core/reset! test.common.loading/show-loading? true)))
           500)))
     :reagent-render (cljs.core/fn [] [1 2])}))

rnagpal21:10:30

(fn [] ~component) is not returned properly from macro

rnagpal21:10:32

component is the first argument, but macro replaces the last argument

darwin21:10:24

@rnagpal : I think you got confused by the fact that you are calling a macro as a function this is possible in cljs repls, macros are functions with two extra hidden parameters, that is why your component is actually unexpected 3-rd arg

darwin21:10:44

@rnagpal I don't fully understand it, but dug this for you: https://github.com/anmonteiro/lumo/issues/30

rnagpal21:10:34

The the hidden parameters were creating problem for me

darwin21:10:47

btw. (println (loader [:div [:div]] [] [1 2])) should not give you what you wanted even if loader macro was expanded properly as expected you want to do (macroexpand-1 '(loader [:div [:div]] [] [1 2])) <- note the quote

Oliver George21:10:09

I don't think I understand how lein decides which version of a library to use.

Oliver George21:10:49

I picked up an old tools.reader version. com.taoensso/encore wanted 0.10.0 and org.clojure/clojurescript wanted 1.1.0

Oliver George21:10:26

My fix was to use lein :exclusions to ignore encore's dep.

Oliver George21:10:38

Sounds like I need to get a handle on hard/soft deps. From lein FAQ... Q: I specified a dependency on version X but am getting version Y; what's up? A: One of your dependencies' dependencies has declared a dependency on a hard version range, which overrides your "soft" declaration.

noisesmith21:10:02

nothing should be using hard versions - two libs specifying different hard versions makes your build fail

noisesmith21:10:17

(in regular maven at least)

Oliver George21:10:56

I can't find a definition of hard dependencies. I presume it's not :depencencies in lein's project.clj

noisesmith21:10:10

I don’t know if lein even has a way to do it

Oliver George21:10:45

Any idea why I'd get the older tools.reader when I have two dependencies wanting different versions?

noisesmith21:10:33

@olivergeorge have you looked at the output of lein deps :tree ?

Oliver George21:10:08

Yes, that's what confirmed the situation.

noisesmith21:10:36

fwiw this is maven’s DSL (I’m not sure how lein maps to it, it might use the same strings?) https://maven.apache.org/pom.html#Dependency_Version_Requirement_Specification

noisesmith21:10:55

you should be able to look at the pom.xml file for the tricky dep (the one :tree blames) and see how it specifies

noisesmith21:10:37

that would quickly confirm or rule out of hard vs. soft deps have any part to play here

noisesmith21:10:11

the pom.xml will be next to the jar in question under your .m2/repository/

Oliver George21:10:52

Thanks, I'll try that. Here's a gist showing the interesting bits of lein deps :tree . https://gist.github.com/olivergeorge/0ee8d39896d52e7c84dabf6eb0625c9b

Oliver George21:10:34

What I didn't expect was clojurescript not having a dep in the first case. Presumably lein said "well I have that dep already so let's not mention it" or something similar.

Oliver George21:10:32

I showed both cases

Oliver George21:10:36

the second one has the exclusion

Oliver George21:10:06

(updated gist, there was a bad copy / paste)

noisesmith21:10:22

I see that now - isn’t it claiming to get the right version now?

Oliver George21:10:48

It is with the exclusion

Oliver George21:10:52

So I have a work around.

Oliver George21:10:50

What worries me is that any dep could demand an earlier version and break my build unless I keep manually excluding them.

Oliver George21:10:08

Just seems odd.

noisesmith21:10:24

doesn’t lein prefer deps earlier in the list over later in the list? so specifying your tools.reader dep closer to the top should help

noisesmith21:10:53

it looks at each dep in the list, depth first, make the version you want show up first

Oliver George22:10:17

pom deps don't seem strange on the surface

<dependencies>
        <dependency>
            <groupId>org.clojure</groupId>
            <artifactId>tools.reader</artifactId>
            <version>1.1.0</version>
        </dependency>
and
<dependencies>
    <dependency>
      <groupId>org.clojure</groupId>
      <artifactId>tools.reader</artifactId>
      <version>0.10.0</version>
    </dependency>

Oliver George22:10:48

@noisesmith Interesting. If that's the case I can work with it.

Oliver George22:10:03

I'll test the theory

Oliver George22:10:47

Yep, that's it.

Oliver George22:10:09

Serves me right for sorting my deps in string order.

noisesmith22:10:23

glad I could help