Fork me on GitHub
#clojurescript
<
2016-10-20
>
turbopape02:10:01

Milestones, the smart project planning assistant, just got 0.3.0 with Natural Language Processing and GANTT! Please have a look on it here: http://turbopape.github.io/milestones/

Oliver George06:10:03

I'm looking for a good technique for delaying loading my cljs app until a js library is ready.

Oliver George06:10:35

In particular I'm experimenting with using Google Charts in a re-frame app. The dynamic loading is causing the problem. https://developers.google.com/chart/interactive/docs/basic_load_libs

Oliver George06:10:39

My CLJS code is executing before the js lib is loaded so I get "Uncaught TypeError: Cannot read property 'DataTable' of undefined" when my code references js/google.visualizations.DataTable.

Oliver George06:10:50

I guess I have to inject <script src="js/compiled/app.js"></script> into the document in the library loaded callback. Feels hacky and if there were two libs like this it'd be extra hacky.

Oliver George06:10:56

Can anyone recommend a better way?

rauh06:10:14

@olivergeorge You're also loading your cljs compiled app dynamically? And the google chars library? Do I understand that correctly?

rauh06:10:18

I've used goog.net.jsloader.loadMany successfully.

Oliver George07:10:55

Thanks I'll check it out

Oliver George07:10:31

@rauh no good reason to load my compiled app dynamically. Just needs to be delayed till the JS Libs have finished their setup work. Google charts have a dynamic load feature which complicates that. I guess the value it adds is avoiding a big page load when not all features are required.

Oliver George07:10:25

The jsloader functions look handy. Thanks.

rauh07:10:23

@olivergeorge Why not just do it with the callback like the link you posted describes it?

rauh07:10:51

It can set a (reactive?) atom. Display "Loading..." when it's one value and use the chart library when it's the other value

Oliver George07:10:38

That's a good idea for this.

rauh07:10:00

I don't do re-frame, I have a mixin that does this for dynamic content in rum, that displays a spinner and a short message.

Oliver George07:10:34

I'd like to go further and extend core.matrix protocols to DataTable class.

Oliver George07:10:50

Meaning ensuring it's there before that namespace loads or wrapping that code into a fn.

Oliver George07:10:11

You've given me good options. Thanks again.

thheller08:10:44

oh nvm 😉

turbopape08:10:28

Wanna see a thinking project planning program written in clojurescript in action? Head over here: http://turbopape.github.io/milestones/

martinklepsch09:10:27

@olivergeorge I made something like this a while ago:

(defn js-loader
  "Load a supplied list of Javascript files and render a component
  during loading and another component as soon as every script is
  loaded. Arg map: {:scripts [] :loading 'component :loaded 'component}"
  ;; TODO turn scripts into a map with a global that can be used to check
  ;; if the script has been loaded before
  [{:keys [scripts loading loaded]}]
  (let [loaded? (reagent/atom false)]
    (reagent/create-class
     {:component-did-mount (fn [_]
                             (.then (jsl/loadMany (clj->js scripts))
                                    #(do (js/console.info "Loaded:" (clj->js scripts))
                                         (reset! loaded? true))))
      :reagent-render (fn [{:keys [scripts loading loaded]}]
                        (if @loaded? loaded loading))})))

martinklepsch09:10:58

@olivergeorge it's reagent but if you use something else it can probably be ported easily

tianshu11:10:23

I'm using draft.js with clojurescript, and met a weird behavior around function call. I have a function that receive 3 arguments,

(defn find-link-entities [content-state content-block callback]
  (js/console.log content-state)
  (js/console.log content-block)
  (js/console.log callback))
And let this function to be called by this line. https://github.com/facebook/draft-js/blob/69890ed57b5f4256cc93ae8e9ea178296851a23e/src/model/decorators/CompositeDraftDecorator.js#L62 The result is the first argument has been ignored, the console prints content-block as the first argument, callback as the second function, and undefined as the last argument.

tianshu11:10:38

Haven't meet any situation like this, very appreciate for any help!

tianshu11:10:12

Sorry, this is not an issues ClojureScript relative. I found my draft.js (which from CDN) only call with two arguments..

thheller11:10:30

@doglooksgood how is the function passed to draft?

tianshu11:10:54

Just provide it as a normal function. Draft's code has been changed, but its document hasn't been updated. According to its document, draft want this function with 3 arguments, but actually it's 2. So the problem solved. 😂

tianshu11:10:22

@thheller Thanks for help anyway.

smogg14:10:57

Howdy, I'm trying to use ReactBootstrap to add its NavDropdown with markup in top-level button. The problem is, content for that button is specified inside :title of that component. As per this issue: https://github.com/react-bootstrap/react-bootstrap/issues/2264, it is possible to use markup there but I'm not sure how would that translate into cljs?

baptiste-from-paris14:10:15

hey guys, someone already had this one ? Uncaught Error: No protocol method ReadPort.take!

baptiste-from-paris14:10:31

I am doing the async clojurescript seminar of cognitect

baptiste-from-paris14:10:46

(defn ex1 []
  (let [clicks (events->chan (by-id "ex1-button") EventType.CLICK)
        show!  (partial show! "ex1-messages")]
    (go
      (show! "Waiting for a click ...")
      (<! clicks)
      (show! "Got a click!"))))

(ex1)

baptiste-from-paris15:10:08

Waiting for a click is displaying but I got the No Protocol error

baptiste-from-paris15:10:39

can’t understand why..

dnolen15:10:24

@baptiste-from-paris the error implies that clicks may not actually be a channel

baptiste-from-paris15:10:57

how is it possible ?

dnolen15:10:39

@baptiste-from-paris I do not know, you might have a made a typo while entering the code in

dnolen15:10:12

one way to check that clicks is a channel is to (js/console.log clicks) before the go block to debug

baptiste-from-paris15:10:16

Got [object Object] ^^

baptiste-from-paris15:10:15

ok, found it… type

dnolen15:10:14

ah k, glad you figured it out

peeja17:10:27

Am I correct in thinking that (cljs.analyzer.api/ns-resolve ns sym) finds a var defined in ns, but not a var aliased or referred into ns, as it only looks at the namespaces :defs?

peeja17:10:15

(whereas clojure.core/ns-resolve does resolve vars via aliases and refers)

peeja17:10:47

Maybe there's a better way to do what I'm trying to do. I have a form, and I know the namespace it came from. I'm trying to fully-qualify the symbols in that form according to that namespace, so things make sense.

peeja17:10:16

Ideally, the form would already come fully qualified, by way of something like syntax-quoting

peeja17:10:48

but in this case, the form is coming from the metadata map from defn, which is automatically (non-syntax-)quoted.

dnolen17:10:44

@peeja it should handle aliases just fine, ns-resolve should call the same machinery the compiler needs

dnolen17:10:31

@peeja sorry I was thinking about resolve

dnolen17:10:11

@peeja agree that ns-resolve should match Clojure’s behavior, ticket + patch (if you like) welcome

mikepjb21:10:40

this is quite possibly a beginner question for clojurescript - I’m trying to set .style.display for an element like so

(defn hide-contact-dialog []
  (aset (.getElementsByClassName js/document "contact") "style.display" "none"))
can someone help me out?

mikepjb21:10:13

I’m using reagent if that helps

dnolen21:10:17

@mikepjb aset isn’t for setting properties, just arrays

dnolen21:10:41

(set! (.. element -style -display) “none”)

mikepjb21:10:22

perfect! thanks @dnolen

mikepjb21:10:41

what is the .. for? is there a good book/resource I can learn more about clojurescript from?

dnolen21:10:41

@mikepjb any good Clojure book will cover the language essentials which aren’t that different from Clojure

dnolen21:10:11

there’s isn’t a up-to-date print book on ClojureScript - but there’s lot of online stuff now

mikepjb21:10:34

the trouble I’m having isn’t with clojure, I’ve written a few projects at work for it - I’m having quite a lot of trouble with javascript interop with clojurescript

mikepjb21:10:52

I’ll have a careful read over the tutorials you linked

mikepjb21:10:00

I’ve probably missed a few points there

dnolen21:10:06

just ask questions here - there’s really not that much you can do

dnolen21:10:48

invoke functions, set properties, interact with JSON values, invoke constructors - just this will take you a long way

dnolen21:10:15

goog.array & goog.object namespaces are useful and worth getting familiar with

mikepjb21:10:51

I didn’t know you could even interact with goog, figured this was all to do with the closure compiler

mikepjb21:10:01

looks like there’s long road ahead

mikepjb22:10:45

@jasonjckn thanks for the recommendation, i’ll check it out

mikepjb22:10:21

does it have javascript interop examples?

jasonjckn22:10:59

yes there's a chapter on javascript interop, the book covers a ton of material with shallow-medium depth

jasonjckn22:10:04

it's a great introduction

jasonjckn22:10:13

if you're looking for high degree of details about interop, i would use docs

romain22:10:53

I got the book too, I liked it. And it gives a good intro to Om by @dnolen here 🙂

jasonjckn22:10:07

it covers "om now" iirc

romain22:10:28

I was typing it doesn’t cover it, they updated the book ?

jasonjckn22:10:51

not sure, I can't remember anymore, i thought it covered some web framework

jasonjckn22:10:42

"Delve into advanced rich web application development concepts such as Om"

romain22:10:43

In my memories, they said it doesn’t cover Om.Next because too shiny when they wrote the book

jasonjckn22:10:05

it covers "om now" for lack of better term

jasonjckn22:10:14

not "om next"

romain22:10:35

Sorry, I read om now 🙃

romain22:10:03

@mikepjb I don’t know if you tried it, but https://github.com/magomimmo/modern-cljs is also nice, plus you learn about bootif you don’t yet

mikepjb22:10:09

I started using reagent because I’d heard it was simpler, it seems a lot of people still use om - is it a good idea to learn om? It seems like there is a lot more learning material for it. Are there any other reasons to learn om over reagent? Are there performance benefits?

mikepjb22:10:34

@romain I haven’t tried it, I’ll have a look - thanks for this!

dnolen22:10:20

@mikepjb if you’re just getting started with Clojure/ClojureScript I would reduce the amount of novelty you have to digest

dnolen22:10:02

om isn’t going anywhere if you decide to check it out down the road 🙂