Fork me on GitHub
#clojurescript
<
2018-09-20
>
Charlot03:09:50

I'm interested in ClojureScript and electron... but I cannot seem to find an up to date template

Charlot03:09:11

Is there a recommended resource I could investigate?

kirill.salykin07:09:57

Hi, I am trying to integrate https://github.com/olahol/react-tagsinput the library expects prop of type string and checks for it

return typeof onChangeInput === 'function' && typeof inputValue === 'string'
but when I convert from cljs regular string is represented as function:
(js/console.log (type (clj->js ""))) => ƒ String() { [native code] }

kirill.salykin07:09:16

please advice what I can do to have just string? thanks

thheller07:09:57

@kirill.salykin a string is just a string. no need for any conversion trickery. how are you passing the value to the component?

kirill.salykin08:09:14

(dom/create-element js/ReactTagsInput
                      (clj->js {:value              tags
                                :onChange           onChange
                                :inputValue         "" #_inputValue
                                :onChangeInput      onChangeInput
                                :addKeys            [9 13 32] ;; tab, enter, space
                                :className          "react-tagsinput form-control"
                                :tagProps           {:className       "react-tagsinput-tag label label-default"
                                                     :classNameRemove "react-tagsinput-remove"}
                                :inputProps         {:placeholder placeholder}}))

kirill.salykin08:09:57

this is fulcro btw

thheller08:09:13

looks correct to me

kirill.salykin08:09:02

thanks so you think it is not in typeof check?

kirill.salykin08:09:40

typeof "" === typeof String
false

thheller08:09:04

thats not what the ehck does

thheller08:09:18

typeof "" === 'string'

kirill.salykin08:09:44

right, but (clj->js “”) returs f String

kirill.salykin08:09:49

not ‘string’

thheller08:09:55

but you are also not calling that ...

kirill.salykin08:09:32

i am not calling what?

thheller08:09:47

(clj->js "")

thheller08:09:13

what is your actual problem? you are probably looking at the wrong place if you think a string is not a string because that is extremely unlikely

kirill.salykin08:09:27

js/console.log (type (clj->js ""))) => ƒ String() { [native code] }

kirill.salykin08:09:45

this is not a string, right?

thheller08:09:09

(let [props
      (clj->js {:value tags
                :onChange onChange
                :inputValue "" #_inputValue
                :onChangeInput onChangeInput
                :addKeys [9 13 32] ;; tab, enter, space
                :className "react-tagsinput form-control"
                :tagProps {:className "react-tagsinput-tag label label-default"
                           :classNameRemove "react-tagsinput-remove"}
                :inputProps {:placeholder placeholder}})]

  (js/console.log "props" props)
  (dom/create-element js/ReactTagsInput props))

thheller08:09:39

yes type is not a string, its the constructor function. it is also not typeof.

kirill.salykin08:09:38

inputValue: ""

thheller08:09:50

why do you think that that is your problem?

kirill.salykin08:09:19

return typeof onChangeInput === 'function' && typeof inputValue === 'string'

thheller08:09:26

so what is onChangeInput?

kirill.salykin08:09:04

ƒ Function() { [native code] }

kirill.salykin08:09:11

it is also not function

thheller08:09:34

that is again type. type does not do typeof.

kirill.salykin08:09:38

k, is it possible to override that function to always return true from cljs?

kirill.salykin08:09:15

> that is again type. type does not do typeof. how I can invoke typeof?

thheller08:09:21

try (js/goog.typeOf thing) if you want actual typeof calls

kirill.salykin08:09:11

seems you are right

kirill.salykin08:09:19

thanks, will debug further

kirill.salykin08:09:18

@thheller problem solved, of course it was my code

pesterhazy10:09:31

why (js/goog.typeOf thing) rather than (goog/typeOf thing)?

pesterhazy10:09:01

or is this a case of the good old Doesn't Matter ^^ @thheller

thheller10:09:04

habit I guess, doesn't really matter no.

mfikes11:09:24

@pesterhazy If it's your preference to set your ns form properly for goog, this was relatively recently sorted: https://dev.clojure.org/jira/browse/CLJS-1677

pesterhazy11:09:19

Nice, that would remove linter warnings @mfikes. Love the attention to detail

witek14:09:09

Hello, I'm stuck again. I would like to build a SPA using cljsjs/material-ui. But how do I use (or create) components like a Button for example?

witek14:09:15

I have put the dependency into my deps.edn and I have required cljsjs.material-ui. But I have no clue how to put any material-ui component into my hiccup... 😞

christos16:09:59

Is there a google closure way to set value in a nested object ? As far as i understand aset is outdated but for nested objects i am not able to use goog.object/set, i have to resort to set!/aset

mfikes16:09:10

@hee-foo You can do a nested goog.object/get to retrieve the object and then do a goog.object/set on it

christos16:09:19

@mfikes. Thanks, it seems really verbose

christos17:09:47

maybe i could reduce on goog.object/get

christos17:09:00

@mfikes I am aware, but i am also upgrading the codebase, i want to avoid another dependensy

christos17:09:17

Thanks again although

mfikes17:09:29

Yeah, in that case you can roll your own

👍 4
lilactown17:09:58

(defn set-in [o path v] ...)

lilactown17:09:32

the lisp curse strikes again 😛

😂 4
christos17:09:36

At least the path is clear.

john17:09:44

FYI, goog.closure does come with a nested getter helper, .getValueByKeys https://github.com/google/closure-library/blob/master/closure/goog/object/object.js#L271

👀 4
👍 4
pesterhazy17:09:10

Looks like someone working on Closure was a fan of Clojure?

mfikes17:09:45

Yeah, "Think of goog.object/getValueByKeys as the JavaScript analog of get-in." (http://blog.fikesfarm.com/posts/2017-11-09-avoid-converting-javascript-objects.html)

mfikes17:09:03

(quote myself) 🙂

👍 4
john17:09:49

That's where I discovered it 🙂

mfikes17:09:54

Me too 🙂

idiomancy17:09:08

So, with re-frame events being modeled after domain concepts. Does anyone here have any opinion on whether events should represent an intention to do something or a statement that something has already happened? For instance, :user/load-address(statement of intention) vs :user/address-loaded(statement of record) does either one of those strike anyone as a pattern to be avoided or a pattern to favor?

idiomancy17:09:05

I had been doing the latter, but I'm starting to think maybe I should favor the former...

lilactown17:09:54

:thinking_face: I can see both being used at the same time?

lilactown17:09:35

:user/load-address -> fetch the address -> :user/address-loaded

idiomancy17:09:06

huh. yeah I guess so. I guess they're kind of like different tiers of event. intentions should have side effects and records should only dispatch intentions

idiomancy17:09:25

if that makes sense

idiomancy17:09:04

Okay, yeah, that makes sense to me. That's probably that I'll end up doing.

lilactown17:09:47

I think that usually you wouldn't really have an :user/load-address event, though. you might have a :user/view-profile event that then triggers the fetching and resolves with :user/address-loaded

idiomancy17:09:36

see, so in that case you are thinking of it in terms of record. user/view-profile is something that happened the user clicked a button to bring up their profile page

idiomancy17:09:44

which is what I was initially thinking too

idiomancy17:09:57

but it weird in cases where other things that can happen that trigger fetching of the user profile, like, I don't know....... comparing your friends list to someone elses, or something

idiomancy17:09:00

so its more like a record -- user-clicked-the-profile-button, and an intention - fetch-profile

richiardiandrea18:09:28

what is the best practice for instrumenting in debug mode an app? I was doing (when ^debug goog.DEBUG (stest/instrument)) in my main namespace after all the requires but the means requiring spec.test in that namespace also in production

richiardiandrea18:09:37

which we don't want ton't we?

richiardiandrea18:09:11

oh maybe I have another idea

thheller18:09:32

(ns your.debug-app (:require [spec.stuff :as x] [your.actual-app :as app])) (defn main [] (x/instrument) (app/main))

thheller18:09:56

ie. switching your entry namespace

richiardiandrea18:09:04

I actually I am requiring the spec namespace in the preload

richiardiandrea18:09:13

and using a fully qualified symbol in the main

richiardiandrea18:09:41

was thinking of abusing shadow-cljs better reader conditionals but got away with that 😄

richiardiandrea18:09:46

thanks Thomas 😄

richiardiandrea18:09:45

@dnolen have you ever though about something like :postloads? because instrumentation should always happen after all the namespaces have been required by the app

Braden Shepherdson19:09:10

so I'm trying to follow https://github.com/magomimmo/modern-cljs but I get a NPE when I try to connect the REPL. am I using bad versions of something? Clojure version 1.8.0, Boot 2.8.2, and importing:

:dependencies '[[org.clojure/clojure "1.8.0"]
                  [org.clojure/clojurescript "1.10.339"]
                  [adzerk/boot-cljs "1.7.228-2"]
                  [pandeiro/boot-http "0.8.3"]
                  [org.clojure/tools.nrepl "0.2.12"]
                  [adzerk/boot-reload "0.5.2"]
                  [adzerk/boot-cljs-repl "0.3.3"]
                  [com.cemerick/piggieback "0.2.2-SNAPSHOT"]
                  ;[cider/piggieback "0.3.9"]
                  [weasel "0.7.0"]
                  [org.clojars.magomimmo/domina "2.0.0-SNAPSHOT"]
                  [hiccups "0.3.0"]
                  [compojure "1.5.2"]
                  [org.clojars.magomimmo/shoreleave-remote-ring "0.3.3"]
                  [org.clojars.magomimmo/shoreleave-remote "0.3.1"]
                  [javax.servlet/javax.servlet-api "3.1.0"] ;; dev only
                  ])

Braden Shepherdson19:09:51

the error is Unhandled REPL handler exception processing message {:id 6fae686a-2f10-435d-bb11-b5772676e3a3, :op clone})

dnolen19:09:58

@richiardiandrea no, I don’t think we need any more stuff here

dnolen19:09:18

you can initialize the app, you can have decorated entry points

richiardiandrea19:09:46

yeah that is what I am doing and this is what we had:

(ns ...)

(when ^boolean goog.DEBUG
  (st/instrument))

(defn -main
  ...)

richiardiandrea19:09:04

but if you put code between the instrument and -main, it won't be instrumented

richiardiandrea19:09:24

so we now have:

(ns ...)

(defn -main
  ...)

(when ^boolean goog.DEBUG
  (st/instrument))

richiardiandrea19:09:49

one could wrap the entry point in another namespace like Thomas was suggesting above

richiardiandrea19:09:01

but :postloads would be definitely cleaner..

dpsutton19:09:17

i think you could do a dev entry that does whatever and then calls the main entry?

richiardiandrea19:09:47

yeah I know I can, just exploring a cleaner alternative

Braden Shepherdson19:09:46

maybe more productive: I'm looking for a current set of dependencies that will work for CLJS on Boot.

thheller19:09:49

@richiardiandrea :postloads is not useful since you can control when something is loaded by their requires. :preloads is misnamed in that way. say your preload has a require for your main entry. that implies that the preload will be loaded after your main.

richiardiandrea19:09:42

well I try not to require the main namespace in the preloads

richiardiandrea19:09:52

but yeah that is another thing to be aware of

thheller19:09:45

why not? I mean the goal of your preload seems to be to instrument the main namespace no?

john19:09:35

@braden.shepherdson Have you checked the versions on those deps? Might want to bump them up to see if one of them is assuming an older lib.

richiardiandrea19:09:39

I basically require the spec.test in preloads and then have:

in preload.cljs

(ns preload
  (:require spec.fully))
(ns ...)

(defn -main
  ...)

(when ^boolean goog.DEBUG
  (spec.fully/instrument))

richiardiandrea19:09:09

also don't want to execute side effects in requiring the main in preload

richiardiandrea19:09:56

that's why I am saying :postloads would solve things for me, and I would not need to care about all this 😄

thheller19:09:44

I don't understand the problem that :postloads would solve here? why does the instrument call have to be in the main ns and not the preload?

richiardiandrea19:09:52

if you instrument in preload you would have to require main in preload...which feels wrong to me...

thheller19:09:08

why does it feel wrong to you? it is not wrong. it is exactly what you want and how you'd express it in code?

thheller19:09:34

why invent some new special config logic for it?

richiardiandrea19:09:43

because :preload should be used for dev tools to setup things right? not for apps

thheller19:09:53

it is staying a preload?

richiardiandrea19:09:56

at least this is what I have always read here 😄

thheller19:09:21

(ns preload (:require [spec.fully :as x] [your.app])) (x/instrument)

thheller19:09:38

stays in :preloads, will be loaded after your.app

richiardiandrea19:09:18

if app has mount state and mount/start, all your state will start in :preload...which again does not feel right...maybe it's just me 😉

thheller19:09:37

what? no idea what that means sorry

thheller19:09:05

nothing will start in :preload? (except the instrument)

richiardiandrea19:09:45

Any main side effect will be executed (I know you shouldn't have any in the first place)..

thheller19:09:43

I have absolutely no idea what you mean. the only thing this code does is moving the instrument call out of your main into the preload

thheller19:09:54

which means that it will be loaded at basically the exact same time?

thheller19:09:08

the "time" at which any main side effect executes basically stays the same?

richiardiandrea19:09:06

Will try to come up with an example later, it is probably due to things we due here, but we have side effects on require and those would be triggered in the preload call with your method

richiardiandrea19:09:25

Lunch time now :)

thheller19:09:41

load order without the preload spec.full -> your.app calling instrument at the bottom

thheller19:09:02

load order with preload spec.fully -> your.app -> preload calling instrument

thheller19:09:50

still don't see a problem 😛

thheller19:09:39

you can even change the require order to get your.app -> spec.fully -> preload

richiardiandrea19:09:00

You might be right, will double check

thheller19:09:06

either way any side effect in main happens before the instrument call regardless

richiardiandrea19:09:53

In terms on ns, spec -> preload -> main feels better than spec -> main -> preload. But without real reasons really

thheller19:09:21

call it postload ^^

thheller19:09:55

better yet call it instrument-app

richiardiandrea19:09:49

Names are important, it will bite me in the back :)

Braden Shepherdson20:09:02

@john I think I have pushed those forward, except that I'm using the classic nrepl (0.2.12) and not the new 0.4.0 with the new namespace. I don't know which namespace the other deps are expecting, though.

john20:09:55

The error you showed did look like it might have come from an nrepl issue

dpsutton22:09:08

done. Successfully compiled build :raw to "target/raw/jib_out/js/jib.js" in 307.214 seconds. 😞

dpsutton22:09:51

just brutal compilation times right now for some reason

mfikes22:09:12

Is that ClojureScript compilation?

mfikes22:09:27

(If so, try master.)

dpsutton22:09:30

ancient days of "1.9.946" 🙂

dpsutton22:09:39

looking forward to finishing up this feature and moving to master

dpsutton22:09:50

also would love to switch to clj and deps.edn

savaki23:09:27

Is anyone familiar with a routing library that works on both the server and the client side?