Fork me on GitHub
#clojurescript
<
2017-06-21
>
deadghost05:06:22

when I include a foreign library, how do I figure out the name of the object to call things from?

deadghost05:06:33

for example, I include an NPM package that has module.exports = React.createClass({ stuff here... })

deadghost05:06:36

in vanilla js it looks like I would var foo = require('foo')

deadghost05:06:56

and use it like foo.whatever

chouser06:06:06

@deadghost Have you tried (def foo (js/require "foo")) and then (.whatever foo arg1 arg2)?

deactivateduser06:06:56

Hi all! I'm experimenting with re-frame and I'm looking for a simple example of password-based authentication. I'm familiar with buddy for ring-based apps, but I'm not sure how to handle this in SPA. Thanks in advance!

deadghost07:06:30

@chouser require is not defined

deadghost07:06:52

not surprised since require doesn't seem like vanilla js

thheller07:06:43

@deadghost you’d need to look at the foreign lib, the name it provides should be available there somewhere

thheller07:06:21

or do you package the foreign lib yourself?

deadghost07:06:00

if by package you mean :file :provides :requires, yes

thheller07:06:38

where does the :file come from?

deadghost07:06:09

I take the file from the dist/ section of a npm package

thheller07:06:32

so that file should contain the name it exports

thheller07:06:23

it will usually be in some kind of UMD wrapper function

deadghost08:06:08

@thheller I should typically look for the export in the src and not the dist right?

thheller08:06:23

no the dist will only contain the final name

thheller08:06:05

which npm package? I can take a look if you want

pseud08:06:07

@deadghost Kinda depends. Regular require works for clojurescript modules which You've imported, e.g.

(ns my-namespace-here
  (:require [foo.bar.baz]
                 [foo.bar.foobar :as f]
                 [my.random.mathlib :refer [myadd mysub]))
(foo.bar.baz/<smth> ...) (f/<smth> ... ) (myadd ...) For NodeJS it's a little different: You need to require the cljs.nodejs NS and use the 'require' function defined therein. See https://mmcgrana.github.io/2011/09/clojurescript-nodejs.html for an example (under the section "Node.js Libraries")

thheller08:06:58

@pseud different issue, foreign libs are only imported via require but their name is not defined by it

pseud08:06:56

Sure, but as the example shows, you just assign the output of require to some var using def and you're done. ? Unless I'm missing something..

thheller08:06:16

but you don’t have require in a browser

thheller08:06:57

for node this works yes

pseud08:06:19

Ah, no. client-side is totally different. That requires wrapping a library, yea.

pseud08:06:30

@deadghost http://github.com/cljsjs project concerns itself with the wrapping of native JS modules for use in front-end CLJS applications. While their build scripts might be a tad advanced for your needs (?) it might be worth looking into, especially if they happen to wrap other react components you might recognize. My understanding is that you need to ensure the code is included in the JS bundle you end up emitting and that it will take an externs file because otherwise the google closure compiler on which CLJS relies for tree shaking will not pick up on your use of the functions defined in the JS lib and simply discard them. I think there were some developments wrt. the need to define extern files, but I haven't looked into it.

thheller08:06:54

@deadghost that looks like the dist file includes its own React. that will not be easy to embed on its own

thheller08:06:38

it also doesn’t seem to provide global name

deadghost08:06:45

@thheller hmm, the non-react version is on cljsjs

deadghost08:06:59

would it be difficult to wrap it for react in cljs?

thheller08:06:25

not sure, I don’t know what it is 🙂

thheller08:06:48

but this is not a whole lot of code

thheller08:06:52

so it should be simple

dominicm08:06:23

Using cljsbuild with a :source-paths set, where should (require) look from the REPL?

dominicm08:06:46

seems to only find clojurescript namespaces if I put them in my top level :source-paths, which I didn't think was the pattern in lein

darwin08:06:05

AFAIK top-level :source-paths are for clj code (macros in cljs) and cljsbuild-level :source-paths are for cljs files only. Paths are implicitly inherited from top-level to cljsbuild-level.

dominicm08:06:59

@darwin you're confirming my understanding. Which puts me back into confusion with: why on earth is the repl failing to require the cljs namespaces?!

darwin08:06:21

I’m not sure if lein-repl knows anything about cljsbuild

darwin08:06:45

it knows only top-level stuff, cljsbuild is just a weird uknown plugin for it, I believe

dominicm08:06:45

I should clarify: this is once I'm in a figwheel repl

darwin08:06:58

aha, so that’s completely different story

darwin08:06:14

figwheel repl understands cljsbuild, I believe

dominicm08:06:35

yeah, afaik it parses the project.clj for the cljsbuild config (even uses spec to validate it now too)

darwin08:06:29

what is odd? “src-cljs” is the default :source-paths if you don’t specify it (cljsbuild default)

dominicm08:06:48

@darwin did not know that! I thought it was odd that it was being set to "src" for cljsbuild also though?

dominicm08:06:11

Oh, it's because it's a cljs-only project.

darwin08:06:03

I don’t follow. Anyways, do you have multiple build-ids in your project.clj? Maybe your figwheel is not picking up the expected one.

dominicm08:06:22

@darwin I have 4. I have done a figwheel-switch & start though. It seems to connect to the browser okay. Reloading works too.

dominicm09:06:47

the build all works. I notice that figwheel 0.5.9 fixed require somehow, so I guess that means something changed in that regard.

dominicm09:06:57

guess I'll try going back a version

darwin09:06:55

you could write a macro and grab effective java classpath in it, maybe that could hint what went wrong

darwin09:06:15

(.getURLs (java.lang.ClassLoader/getSystemClassLoader))

dominicm09:06:32

on 0.5.8, (require) works, but (ns cljs.user (:require 'foo)) does not

dominicm09:06:18

load-namespace does not work.

thheller09:06:43

@dominicm don’t quote in ns

thheller09:06:06

(require 'foo) for the REPL but (ns cljs.user (:require foo))

dominicm09:06:11

I wasn't, that's just my own foolishness here.

thheller09:06:49

not sure about the figwheel issue you are seeing but you can add your :source-paths for lein as well

thheller09:06:18

so not just in :cljsbuild but at the “top”

thheller09:06:42

nvm you said that yourself 😉

dominicm09:06:00

@thheller it's crossed my mind already to try shadow cljs tbh 😛. We'll see how long my resilience holds up for fixing this.

dominicm09:06:08

Hopefully it's just a mismatched versioning somewhere.

thheller09:06:24

do it already! I have nrepl almost ready

dominicm09:06:12

@thheller > almost ready I gotta have me some vim integration.

qqq10:06:45

is there a way to contro browsers using cljs ?

qqq10:06:58

i.e. I want to fire up a browser (which ran run js), then I want to control this browser via clojure/cljs

dominicm10:06:13

@qqq That's what a figwheel repl is, or the weasel repl thing.

qqq10:06:31

that's hot code reloading

qqq10:06:47

I want to do things in cljs to sa y"fire up browser, go to http://flights.google.com, search for BLAH to BLAH, get the HTML, parse the table"

qqq10:06:57

I think 'selenium' and 'webdriver' are the related techs

dominicm10:06:09

@qqq oh, browser automation. By "control browsers" I thought you just meant code execution.

zilti10:06:46

@qqq maybe it's more efficient to create a JavaFX web view and control that one directly via Clojure instead of ClojureScript.

qqq10:06:56

can I grab the dom tree

qqq10:06:06

to do things like "grab the input field with id BLAH, and set its value to FOOBAR" ?

zilti10:06:45

@qqq I only ever played around with it and got stuff out by injecting JS, but I'm pretty sure you can (javafx.scene.web.WebEngine#getDocument)

thheller11:06:27

@qqq those tools are usually driven by JS code .. you can write that JS code in CLJS

octahedrion12:06:37

how do I extend-type Object in Clojurescript ?

Roman Liutikov12:06:48

@octo221

(extend-type object
  YourProtocol
   ...)

Roman Liutikov12:06:23

how do you test this?

octahedrion12:06:15

well, what I mean is, extend-type object should be the default implementation, but when I throw a boolean at it I get: No protocol method Rendering.render defined for type boolean: false

Roman Liutikov12:06:57

a snippet of code would be useful

octahedrion12:06:16

ok, in Clojure you can do this:

(defprotocol Q (q [this]))
=> Q
(extend-type Object Q (q [this] 8))
=> nil
(q 7)
=> 8

octahedrion12:06:53

but in Clojurescript:

dev:cljs.user=> (defprotocol Q (q [this]))
nil
dev:cljs.user=> (extend-type object Q (q [this] 8))
#object[Function "function (this$){
return (8);
}"]
dev:cljs.user=> (q 6)
#object[Error Error: No protocol method Q.q defined for type number: 6]

mfikes12:06:32

(extend-type default Q (q [this] 8)) is possible

mfikes12:06:05

See the docstring for extend-type for more details

octahedrion12:06:39

stupidly I was reading the documentation for protocols

octahedrion12:06:33

but does the rule of using lowercase names of types, like boolean not Boolean, follow in CLJS ?

octahedrion12:06:43

- for extending other types

octahedrion12:06:37

hmm ok so

Keyword
for keywords, but
number
for Numbers

mfikes12:06:04

@octo221 You can use js/Number, but it is discouraged. (It will also cause a compiler working to be emitted.)

octahedrion12:06:58

ok but no cross-platform way of denoting a type ?

mfikes12:06:48

That’s an interesting question. I’m not aware of built-in ways to abstract over hosty aspects. Generally that stuff is put into reader conditionals these days, I suppose.

octahedrion12:06:01

of course, fine. Hey thanks for your help @mfikes !

husayn14:06:02

anybody been able to get npm-deps to work with om.next + figwheel ?

husayn15:06:47

thanks, i'll check it out

dnolen15:06:58

@octo221: there no cross-platform way to talk about native JS types because the types themselves are too host-y

dnolen15:06:07

Number is a great example of this

manu16:06:11

hi! I need to

import CardStackStyleInterpolator from 'react-navigation/src/views/CardStackStyleInterpolator' 
as described in this issue https://github.com/react-community/react-navigation/issues/1400. How I can do? Thanks 🙂

octahedrion17:06:51

@dnolen understood, except, if a thing returns true for number? then it's of type Number (in some sense) - or am I thinking about types all wrong ?

octahedrion17:06:36

@dnolan hmm, thinking about it, another way to test for a type, other than by its name, is to ask what functions can it can be applied to. Like respondsTo: in Smalltalk

jjttjj17:06:25

what's the best way to convert edn to json while preserving namespaced keywords?

jjttjj17:06:53

from clojurescript

noisesmith17:06:03

there’s the fundamental problem that json has neither keywords nor namespaces…

noisesmith17:06:23

so you need to set up a conversion convention I guess

ag18:06:37

can anyone tell me when to expect perf. improvements @mfikes was talking about recently (to be released)

mfikes18:06:12

@ag I heard David mention perhaps targeting Friday release, IIRC

mfikes18:06:39

@ag There are a boatload of changes in master right now, so it is worth giving them a spin.

ag18:06:13

this Friday? parrot

mfikes18:06:23

Yes. On Tuesday, he used the term “Friday”. 🙂

ag18:06:46

well, if a programmer says Friday it can mean Friday in June, December or in month of Phobos based on a Martian calendar 😉

ag18:06:03

still, I am very excited! Thanks @mfikes

mfikes18:06:03

Yeah, it is good stuff. 🙂 If you look in JIRA, there is a roadmap, with 20 unresolved issues targeting the Next release. If all of those are to be done, then Friday would be a challenge, IMHO. Dunno if that’s really the plan.

tjtolton18:06:54

So, every time I try to get started with cljs, I get terrified by framework and tooling choice.

tjtolton18:06:57

it feels like picking the wrong framework will lead me to wasting weeks and weeks of effort as I slowly realize that the framework is either too opinionated so it prevents me from doing what I want, or it's not robust enough so it prevents me from doing what I want

tjtolton18:06:48

do I want to learn ohm.next and have plenty of rope to hang myself, or use brutha and have to make all my rope from tree bark?

ag18:06:58

@tjtolton: from my personal experience: switched to Boot - regretted for not switching sooner. used Reframe, then tried Om.Next - to be honest this one was really hard, regretted for not using Untangled.

tjtolton18:06:52

regretted what? switching or not switching? or not switching to the right thing?

ag18:06:49

I should've switched to Boot sooner. It does make more sense for front-end projects IMO

ag18:06:01

if you pick up Om and have to use it in a project with more than 3 people, I strongly suggest someone to become "expert" and then patiently explain it to others. Otherwise it would be really hard

ag18:06:55

there's something about Om.Next's novelty approach. Everyone who starts learning it, soon starts questioning its design. Most of the time without fully understanding it

tjtolton18:06:32

and then I have to choose boot or lein, and that's a weird philosophical dilemma

tjtolton18:06:51

where boot is practical, flexible and composable, but its also unstable, imperative, and side-effect first design. Lein is declarative, pushes side-effects to the edge, battle tested, stable etc, but apparently it quickly becomes a nuisance since cljs is mostly file transformation

mobileink21:06:56

tjtolton: lein is fine, but boot is woot. why do you think boot is unstable? re: side-effects, boot is very functional, filesets are immutable.

tjtolton21:06:25

oh, I guess because I was looking at old info, is the short answer

tjtolton21:06:43

It was probably unstable 2 years ago when I started looking at it

mobileink21:06:02

tjtolton: yeah there have been major improvements, i think its pretty stable now, and pretty widely-used.

tjtolton00:06:14

@U0LGCREMU also, I just want to say that I am completely sold on boot exclusively because of that sweet rhyme

tjtolton00:06:52

A rhyme is as good a reason as any to navigate a balanced decision tree

tjtolton18:06:10

someone help me through my existential crisis 😅

tjtolton18:06:57

there's got to be a stickied topic for this somewhere. people probably ask every ten minutes.

mattly18:06:10

@tjtolton there's no wrong answers

miikka18:06:16

boot/lein: i've used both a lot and they both work just fine.

mattly18:06:48

if you want to learn clojurescript any of these things are going to help you there, but you're also going to be learning something else along with

tjtolton18:06:15

mattly: yeah, I guess my question is which choice will lead to the most transferrable something else

mattly18:06:27

none of them, really

tjtolton18:06:32

like, learning the JVM will help you out even if you abandon clojure

mattly18:06:45

I guess I'd come back with, what's your goal here?

mattly18:06:45

om.next is well-suited towards a particular problem, but if your goal is just to build a simple side-project it's way overkill

tjtolton18:06:47

2 goals. 1 is a specific app I want to make, and then grow and support it if it becomes something people are interested in. 2 is learn how to make that process repeatable

mattly18:06:39

what I've done for front-end tools is try them out on something simple to see how I like them

tjtolton18:06:46

@U053V4R5N makes sense I suppose. I have something simple in mind, but I am going to have a limited time to implementation, and I basically get one doover

mattly18:06:06

just as I had to learn a lot about the JVM at the same time I was learning clojure

dealy18:06:13

hi, are there potential issues with core.async pub/sub in cljs? I have a publication for which I have 2 subscribers which listen for different events on the same topic

dealy18:06:46

It looks like I'm only getting notifications to one subscriber at a time, like I get a bunch of messages for sub1 and nothing happens on sub2 and then later the roles are reversed, all the while I see messages for both event1 and event2 being pushed on to the channel that the pub is associated with

dealy18:06:26

javascript doesn't have threading like the JVM so I'm wondering if maybe I'm expecting too much here?

dnolen18:06:12

@dealy without a minimal example hard to say what the problem is

dealy18:06:36

sure, making something small that accuratly reflects what I'm doing is a bit of a chore but I'll try. I was mostly just checking to make sure that it makes sense to be able to expect channels to handle many things happening at the same time in clojurescript

dealy18:06:53

I have something like this (def bus (chan)) (def t-pub (pub bus :topic1)) (def sub1-ch (chan)) (def sub2-ch (chan)) (defn looper [ch handler-fn] (go-loop [] (handler-fn (<! ch)) (recur))) (sub t-pub :evt1 sub1-ch) (looper sub1-ch sub1-handler) (sub t-pub :evt2 sub2-ch) (looper sub2-ch sub2-handler)

dealy18:06:34

and then lots of things push on to the bus (go (>! bus {:topic1 :evt1 :payload "foo")) (go (>! bus {:topic1 :evt2 :payload "bar")) etc

dealy19:06:42

pushing stuff on to the bus is interleaved between evt1 and 2 pretty heavily, however the actual calling of the the functions sub1-handler and sub2-handler aren't really interleaved or maybe there is slight overlap for just a moment

ag20:06:16

how do I get a meta of fn that's passed as param?

ag20:06:09

(fn [f] (meta f)) or (meta (var f)) doesn't seem to work

ag20:06:04

need some magic quoting or something?

thheller20:06:23

functions are JS functions, they don’t have metadata

ag20:06:50

oh... how do I get arity of f then in the case above?

thheller20:06:27

no reliable way to do so

thheller20:06:36

there is (.-length f) property

thheller20:06:50

that is incorrect in many cases

qqq21:06:23

I have embedded a cljs repl in my app.

qqq21:06:31

Next, I want to embed a miny editor.

qqq21:06:35

Suggestions ?

mfikes21:06:17

With respect to the above, function values appear to be able to convey meta

mobileink21:06:36

sanity check needed. i have clojure data to send to my cljs frontend, which stores it in datascript. i understand transit would be more efficient than edn at least in some cases, is that right? but then my frontend needs to pass some of that data to java objs (webcomponents). clj->js works, but i'm wondering how others handle this situation. is there is a best practice for this sort of thing? e.g. i could drop datascript and move query/filter logic to the backend and just send javascript.

qqq21:06:47

@darwin: funny, I was just looking at paren-soup (the 'editor' part of nightlight)

dealy21:06:45

more questions about pub/sub, it appears that some of the items I'm putting on to the channel are just being dropped. in some instances its every other item that is put, never has a corresponding take. What could account for this?