Fork me on GitHub
#clojurescript
<
2017-10-17
>
briantrice05:10:39

I’m wondering how I can make an external library initialize when it provides no externs: https://github.com/cljsjs/packages/tree/master/smoothscroll-polyfill https://github.com/iamdustan/smoothscroll

briantrice05:10:32

ah, it is getting called

briantrice05:10:20

unfortunately, it believes the browser which I’d prefer to override.

dhirensr06:10:06

hey how can we convert this into cljs $(window).load(function() { $(this).joyride(); }) and i tried it like this :component-did-mount #(.load (jq/$ "window") (fn [] (.joyride (jq/$ "#first")))) but it's not working. can any one tell whats the right way?

thheller06:10:53

(jq/$ "window") -> (jq/$ js/window)

thheller06:10:43

using this in the JS example but (jq/$ "#first") in CLJS?

dhirensr06:10:04

i didn't know how to use this in the cljs so can i use (.joyride (jq/$ "this"))? @thheller

thheller06:10:40

(this-as x (jq/$ x))

dhirensr06:10:45

so now

(.load (jq/$ js/window) (fn []
                                                    (.joyride (this-as x (jq/$ x))))) 
is this right? @thheller

thheller06:10:36

looks correct yeah, safer to have this-as immediately after fn but should be fine

hkjels07:10:54

is there a fn I can use along with select-keys to preserve the order?

thheller07:10:23

@hkjels maps are unordered

hkjels07:10:56

hmm.. Just testing at the REPL I can see that you can manually order a map I can also see that select-keys keeps the order, so I’m not sure why it doesn’t happen for my use-case

thheller07:10:33

clojure has 2 map types, array-map and hash-map. array-map is ordered but becomes hash-map at a certain threshold

thheller07:10:40

so you cannot rely on maps being ordered

hkjels07:10:01

ahh.. then it makes sense

thheller07:10:02

I think the threshold is 8?

thheller07:10:18

array-map is optimized for small maps

hkjels07:10:41

OK. I convert it to a seq later on anyways, so I’ll just move that around

hkjels08:10:06

@thheller worked like a charm 🙂

borkdude09:10:39

@metametadata Do you mind if I ask a few questions regarding Etaoin setup?

Bravi09:10:42

when using cljsbuild, how can I define a default profile? Or do I need to always specify lein cljsbuild once <whatever>?

abp10:10:09

Hey we noticed random-uuid is using Math/random via rand-int, would it be better to use js/window.crypto.getRandomValues to get cryptographically strong pseudo random numbers for UUIDs or is Math/random used intentionally because it is sufficient?

dnolen10:10:56

@abp we don’t use things directly that aren’t available broadly

dnolen10:10:25

but probably a patch to use a better PRNG if available would be OK

dnolen10:10:10

ideally we don’t do this ourselves, but rely on Google Closure to chose the right thing

abp10:10:19

@dnolen ok I'll look into it and ask if anything comes up or just provide a patch

mseddon12:10:11

@abp Math.random is not sufficient for cryptographically strong uuids

abp12:10:16

@mseddon alright, thanks, patch should be up soon

mseddon12:10:25

🙂 great work!

roklenarcic12:10:14

Hey guys I want to use goog.date.UtcDateTime but I don't know how to import it and call it, can someone help me?

Roman Liutikov12:10:41

if it’s a class, import with (:import goog.date.UtcDateTime)

Roman Liutikov13:10:25

then refer to it directly, create an instance for example (goog.date.UtcDateTime.)

roklenarcic13:10:53

I used (:import [goog.date UtcDateTime])

roklenarcic13:10:36

so to call methods on objects of this class I do (.toUTCIsoString d)?

roklenarcic13:10:33

The problem I'm trying to solve is that on server I have UTC timestamps and on client I have local times. I'm looking for a way to convert from/to and I can't find it in google closure library

mfikes13:10:14

@mseddon Yes. Furthermore, you shouldn't need to :refer [my-macro] inside foo.bar.

mseddon13:10:57

@mfikes great, thanks!

tobowers14:10:55

I’m having a really weird problem… I depend on an npm module jwt-decode. When I’m using figwheel and do a lein clean and then a lein figwheel everything is fine. But if I refresh the page, I get the not-found error (

Undefined nameToPath for module$Users$tbowers$code$quorum$manager$node_modules$jwt_decode$lib$index
). If I lein clean and lein figwheel again everything is fine. Also, in general - hot reload works too… so it’s only when I actually click refresh

tobowers14:10:31

I’m just doing a normal (:require [jwt-decode]) in the namespace that’s using it

abp14:10:13

If I need a conditional require for nodejs in cljs/core.cljs, is there a place to put it, like a preamble that's only loaded for node? Alternatively I could do it based on target Do we even want a nodejs-require for crypto in ClojureScript?

metametadata15:10:12

@roklenarcic one of the solutions is to use Unix Epoch milliseconds when communicating between frontend and backend. Look at goog.date.DateTime.fromTimestamp or an even simpler (js/Date. epoch-millis).

tomaas15:10:34

hi, I have a component [comp] instantiated inside a component X. Based on some change in component X I want [comp] to be re instantiated (so it executes its did-mount function, and not only render). Is there some way to do it without moving the local state of comp to X?

pesterhazy15:10:30

better to register a component-did-update lifecycle method as well as component-did-mount

pesterhazy15:10:18

a nice pattern is to define a smart "inner" component that receives the relevant values as props

tobowers15:10:59

@abp - I was wondering the same thing and I ended up with different builds for frontend/backend that just didn’t include node files. If you need it in the same ns I suggest using target

tobowers15:10:06

as far as I can tell there was no built in conditional

tobowers15:10:35

alternatively, specifically for crypto, you could use one of the shims that does the right thing in both situations and then you’d just be using the regular (:require

abp15:10:07

@tobowers Thanks, but I'm working on ClojureScripts core.cljs to improve the random-uuid function, so I'm writing a shim there for the patch, on node it seems to be a bit more challenging

jaeschliman17:10:35

Hello all, what is a good starter kit these days for building a Full-Stack SPA using WebSockets and re-frame for the front end? Thanks!

yury.solovyov17:10:09

I've received a suggestion in #re-frame to use https://github.com/Day8/re-frame-template

Reut Sharabani19:10:56

what is the meaning of #js that I see everywhere?

Reut Sharabani19:10:04

I'm pretty new to clojure and clojurescript

yury.solovyov19:10:10

It creates js object or array literal

pesterhazy19:10:23

ClojureScript's "missing manual"

levitanong19:10:54

Hi all, (keyword :foo :bar) works in cljs, but throws in clj. I’ve checked the source and it seems intentional on the cljs side, and has been this way for 4 years. Does anyone know why this is so? edit: should be arity 2, not 1

noisesmith19:10:27

there are a lot of things in cljs and clj that work accidentally but aren’t intended features, especially in regards to creating valid keywords and symbols

noisesmith19:10:30

that said, I don’t know if the discrepancy is an accidental feature of cljs or just an intentional difference between the languages

noisesmith19:10:25

well - it’s definitely not a clj bug, I guess you could arguably call any unintentional feature a bug

dpsutton19:10:25

well, his point is kinda "a bug in which language"

noisesmith19:10:32

not a clj bug

noisesmith19:10:58

maybe cljs bug, maybe cljs feature, maybe “unintentional feature” ?

levitanong19:10:06

it seems to be an intended feature in cljs because there is a cond clause specifically testing for keyword?

levitanong19:10:11

so it’s definitely intentional

noisesmith19:10:17

good to know

levitanong19:10:04

which makes me wonder if it’s a planned feature for clojure, and they just haven’t gotten around to implementing it.

noisesmith19:10:23

I’d suspect not a planned feature - it would be easy to implement

noisesmith19:10:38

wait - it doesn’t throw in my clj? did you have the cases backward?

noisesmith19:10:01

user=> (keyword :foo)
:foo
user=> *clojure-version*
{:major 1, :minor 8, :incremental 0, :qualifier nil}

levitanong19:10:29

Oh sorry, it should be arity 2

levitanong19:10:34

(keyword :foo :bar)

noisesmith19:10:55

oh, OK - that makes more sense, thanks

noisesmith19:10:20

and given that case, I do wonder whether they intend for parity or if it’s a difference in api…

dpsutton19:10:24

(defn keyword
  "Returns a Keyword with the given namespace and name.  Do not use :
  in the keyword strings, it will be added automatically."
  {:tag clojure.lang.Keyword
   :added "1.0"
   :static true}
  ([name] (cond (keyword? name) name
                (symbol? name) (clojure.lang.Keyword/intern ^clojure.lang.Symbol name)
                (string? name) (clojure.lang.Keyword/intern ^String name)))
  ([ns name] (clojure.lang.Keyword/intern ns name)))

dpsutton19:10:52

are you sure that's not a bug in clj? There's a lot of care in the first arity that is just ignored in the two arity version

dpsutton19:10:16

is cljs overly permissive or clj under permissive?

levitanong19:10:20

I am but a mere peasant. How could I presume it’s a bug in CLJ? 😛

dpsutton19:10:49

well i don't know where to find a specification of what it /should/ be so i suppose that the implementation is the reference

levitanong19:10:03

I would tend towards considering this as CLJ being under permissive though.

dpsutton19:10:36

i'm just going on the fact that there is some consideration of different types in the 1 arity branch which they explicitly ignore in the second. but i suppose you need to see what /intern looks like

noisesmith19:10:21

how about (fn ([x] (keyword x)) ([x y] (keyword (name x) (name y))) as a portable version - any gotchas there?

levitanong19:10:44

well if you passed a string, it would throw.

noisesmith19:10:00

user=> (name "foo")
"foo"

dpsutton19:10:09

user> (keyword :hi)
:hi
user> (keyword "user" "hi")
:user/hi
user> (keyword "user" :hi)
ClassCastException clojure.lang.Keyword cannot be cast to java.lang.String  clojure.core/keyword (core.clj:595)

noisesmith19:10:10

name is the great equalizer between str / kw / sym

dpsutton19:10:14

that's a bug in clj i think

dpsutton19:10:29

i can intern :hi, "user" "hi", but not "user" :hi

noisesmith19:10:45

well - as long as namespaces are out of scope (as they should be with two args anyway)

dpsutton20:10:12

i'm not sure what that means

noisesmith20:10:36

(name :foo/bar) - “bar”

noisesmith20:10:54

that’s where it’s lossy - but with two arg keyword call you don’t care about that case - it is nonsense in that instance

Reut Sharabani20:10:14

thanks for the answers here 😛

levitanong20:10:21

anyway, thanks for the thoughts, @dpsutton and @noisesmith! I will retire to bed now

yedi20:10:38

is there any point to using something like https://github.com/funcool/struct over core.spec?

yedi20:10:12

i think luminus uses struct and am wondering if its outdated in doing so

msolli20:10:31

I find struct is really nice in route handlers, for validating form input and providing nice error messages to users.

msolli20:10:16

Spec does not have the same ergonomics in this usecase (yet).

yedi20:10:26

i was considering using it for client side form validation, but our server already has a ton of core.spec code, an i'm wondering if it makes more sense to try to repurpose the spec code

msolli20:10:28

There’s been some recent discussions on this topic over in #clojure-spec.

yedi20:10:21

hm from my cursory looking at the optinos, seems like struct has the best semantics for doing frontend validation

Ertugrul Cetin22:10:45

Hey Guys, I’ve open sourced Clojurecademy 🎉🎉🎉 https://github.com/clojurecademy/clojurecademy

coetry23:10:32

thank you for your graciousness, may graciousness come back around for you 🙏