Fork me on GitHub
#clojurescript
<
2017-01-14
>
leo.ribeiro02:01:43

hello guys! what editor do you recommend to use nowadays?

sova-soars-the-sora04:01:31

@leo.ribeiro Lately I use LightTable and a few terminal windows to do most of my developing. Atom has ProtoREPL that is cool. The next step up, imo, is Emacs and that can be its own adventure in itself. There are some projects on github that have very nice initial settings like Prelude or the one by Bodil..

leo.ribeiro04:01:37

@sova thannks for the feedback… I’m giving a shot on Emacs… enjoying but what a challenge haha

sova-soars-the-sora04:01:13

@leo.ribeiro my most productive coding days are from my emacs days. M+x cider-jack-in 4life

sova-soars-the-sora04:01:58

Right now I've been tinkering, since it's less codingcoding and more design. Flexibility in tooling. Emacs undo tree is excellent, though! Much missed feature from the rest.

mikethompson08:01:13

@leo.ribeiro @sova The Clojure Survey asks this question so we have data. The following link is one year out of date, but it is indicative (search for "DEVELOPMENT ENVIRONMENT" on this page): http://blog.cognitect.com/blog/2016/1/28/state-of-clojure-2015-survey-results My guess is that Cursive will be higher when this year's figures are published. It is commercial, but some regard it as having an easier learning curve than emacs. Shrug. Depends what you already know.

pesterhazy09:01:20

@stuartsierra I ran into a very similar issue the other day and it turned out to be an order of evaluation issue: https://github.com/cljsjs/packages/issues/697#issuecomment-271292601

leov09:01:33

did someone encounter "Malformed transit" exception when making requests from cljs-ajax to ring-transit middleware?

leov11:01:11

ok I can't seem to find a working combination of ring middleware and cljs client to send clojure datastructures request from browser to server 😞

martinklepsch11:01:36

@leov when you inspect the transit that’s being sent, can you decode it on the repl?

leov11:01:00

I use

(-> (:body @tmp) #_(java.io.ByteArrayInputStream. (.getBytes @tmp))
      (cognitect.transit/reader :json)
      (cognitect.transit/read))

leov11:01:36

also my client does send application/transit+json content type

leov11:01:16

second middleware does the decoding but throws EOF exception

leov11:01:24

first one doesn't seem to do anything

leov11:01:32

second is simpler so should be easier to debug, but I don't know what to do next. I can decode the body myself through the snippet above, and it more or less matches to the decoding in middlewares code

leov11:01:49

I don't know what debugging technique to apply. Currently I do (reset! tmp ring-request) in my ring handler, but :params is empty there, and :body is unchanged

leov12:01:08

ok, this means that cljs-ajax/PUT is somewhat incorrect in this form `(PUT "/transact" {:params (select-keys @my.w/server [:net-config]) :handler (fn [r] (swap! my.w/server merge r))})`

pesterhazy12:01:14

have you tried POST instead of PUT?

pesterhazy12:01:49

try to find a minimal reproduction of the problem

pesterhazy12:01:06

ideally, capture the request in the chrome devtools and use "copy as cURL"

pesterhazy12:01:30

then repeat from the command line, with the simplest possible data structure

pesterhazy12:01:24

we use ring-transit + cljs-ajax successfully, and so do many others

leov12:01:51

I have the simplest map {:a "hi"} or so

leov12:01:04

in chrome devtools request looks ok

leov12:01:46

I am able to manually decode it via the snippet above, but ring-transit middleware somehow I guess reads it twice or something, judging by the exception java.io.EOFException

leov12:01:08

I am now digging further by hotswapping the middleware functions code

leov12:01:23

and doing (reset! tmp-atoms ..)

leov12:01:37

I can change PUT to POST

leov12:01:37

it's still

[#error {
 :cause nil
 :via
 [{:type java.lang.RuntimeException
   :message "java.io.EOFException"
   :at [com.cognitect.transit.impl.ReaderFactory$ReaderImpl read "ReaderFactory.java" 114]}
  {:type java.io.EOFException
   :message nil
   :at [com.cognitect.transit.impl.JsonParser parse "JsonParser.java" 44]}]
 :trace
 [[com.cognitect.transit.impl.JsonParser parse "JsonParser.java" 44]
  [com.cognitect.transit.impl.ReaderFactory$ReaderImpl read "ReaderFactory.java" 112]
  [cognitect.transit$read invokeStatic "transit.clj" 297]
  [cognitect.transit$read invoke "transit.clj" 293]
  [ring.middleware.transit$read_transit invokeStatic "transit.clj" 35]
  [ring.middleware.transit$read_transit invoke "transit.clj" 27]
  [ring.middleware.transit$transit_handler$fn__6723 invoke "transit.clj" 57]

pesterhazy12:01:02

what other middleware do you use?

pesterhazy12:01:15

try removing it all except for ring-transit

pesterhazy12:01:20

also remember that order matters

pesterhazy12:01:53

the request body in ring is a InputStream which can only be read once

pesterhazy12:01:14

if you "slurp" it once, it's gone

leov12:01:34

the exception points to that. I am puzzled because when I disable this exact middleware, I am able to slurp the body, however when I enable this last middleware, it throws the exception as if it somehow have the body already slurped

pesterhazy12:01:53

can you post your midleware pipeline?

leov12:01:48

meep.

(defn wrap-everything [handler {enable-csrf? :enable-csrf?}]
  (-> handler
      ;; (wrap-restful-format :handlers [])
      ;; (ring.middleware.format-params/wrap-transit-json-params)
      ;; (ring.middleware.format-response/wrap-transit-json-response)
      wrap-transit-response
     (wrap-transit-body {:keywords? false        ;  ;
                          :malformed-response-fn (fn [e r h] (reset! tmp [e r h]) {})
                          })
      (wrap-defaults (-> (if (= (env :clj-env) "production")
                           (-> secure-site-defaults
                               (dissoc-in [:security :hsts])) ; TODO: remove; always returns empty 200 for some reason
                           site-defaults)
                         (assoc :proxy true)
                         (my.tools/deep-merge {:session {:store
                                                         (cookie-store {:key (or (env :secret-key)
                                                                                 "dev-key 16 bytes")})}})
                         (#(if enable-csrf? % (dissoc-in % [:security :anti-forgery])))))
      wrap-cljsjs
      wrap-with-logger
      wrap-gzip))

(def http-handler
  (compojure.core/routes (wrap-everything (-> (compojure.core/routes my.saml/routes))
                                          {:enable-csrf? false})
                         (wrap-everything (-> routes
                                              (my.saml/wrap-allowed-users allowed-user?)
                                              my.saml/wrap-saml-authentication)
                                          {:enable-csrf? false})))

pesterhazy12:01:34

are you calling routes twice?

leov12:01:08

maybe. how to figure out if I do? my compojure main routes table is simple:

leov12:01:23

(defroutes routes
  (GET "/" _
    {:status 200
     :headers {"Content-Type" "text/html; charset=utf-8"}
     :body (io/input-stream (io/resource "public/index.html"))})
  (GET "/world" {session :session}
       {:status 200
        :body (merge @world
                     {:current-user (:saml session)})})
  (POST "/transact" {:keys [session params] :as req}
       {:status 200
        :body (do
                (reset! tmp req)
                (merge @world
                     {:current-user (:saml session)}))})
  (resources "/"))

pesterhazy12:01:11

I'd get rid of everything and start with a minimal pipeline

pesterhazy12:01:16

especially remove wrap-defaults

pesterhazy12:01:58

also you should have a reloading setup so you don't have to restart the repl to make changes to the middleware 🙂

pesterhazy12:01:09

that makes all the difference, believe me

leov12:01:10

yes, I do have that. one that comes with ring, I believe

leov12:01:25

removed all middlewares but wrap-transit-body

leov12:01:28

it persists)

pesterhazy12:01:57

try restarting the repl?

pesterhazy12:01:21

also get rid of the routes entirely 🙂

pesterhazy12:01:10

it may be that ring-transit is run twice

pesterhazy12:01:24

(you may actually see that in the full stacktrace)

leov12:01:20

interesting

leov12:01:33

looks like this is it

leov12:01:37

right there where I compose two different handlers, and wrapping them with my 'defaults' vinaigrette

leov12:01:47

omg. thanks a lot.

leov12:01:58

telepathy

leov13:01:00

you sir have quite a debugging skills 🙂

leov13:01:33

also I've no idea how to write compojure routes in a safer manner. it's the second or a third time I shoot myself in a foot. Move middlewares up or a down the stack a little, or try disabling CSRF for some routes - and the best would be something like this, and other times it will be a plain security problem

quartz13:01:15

Hey peeps! I'm working on an ECS library for clj/cljs with the target being for game dev in cljs coupled with either a pixi.js or phazer.js wrapper. I've got something set up atm but I'm not too happy about the performance (I know running on JS doesn't help) and I was wondering if anyone would have any tips on what data structures to use and maybe operations on those data structures. I 'm trying to keep if fully functional with immutable data structures, not sure if it will be possible because of the performance penalization, but I'm not too informed on how to optimize the clojure datastructures

pesterhazy13:01:44

@leov, I find using bidi a bit easier

pesterhazy13:01:29

well ok yesterday I spent an hour debugging a bidi problem (my fault of course) but in general it's a bit less magical

leov13:01:04

@pesterhazy, for this example - 1) I must test some routes in compojure without CSRF protection, then move on to main app logic. 2. I want CSRF protection to be before any other middleware 3. I want ring-transit middleware am I correct it's just impossible to satisfy all 3 with compojure and ring?

leov13:01:27

just impossible - because ring-transit will be called twice

leov13:01:52

because if I am not mistaken - compojure test the route LAST, right?

leov13:01:00

if I am correct, compojure goes something like this (some-> handler1 handler2 ..) well during the compilation I guess, with macros (might be very wrong about this)

leov13:01:37

ok thank you very much

pesterhazy13:01:45

no problem at all

triss13:01:00

hey all. I keep being told by CIDER that NAmespaces don’t exist.

triss13:01:22

is there any rules about namespace names that are cljs specific?

triss13:01:38

do I need to be more careful with hyphens or something?

mavbozo13:01:01

@triss what are you trying to do?

triss13:01:18

oh keep getting an issue where one of my I’m told one of my namespaces does not exist

triss13:01:52

I’m working in a lein re-frame … generated project

triss13:01:06

in figwheel etc

triss13:01:43

and when ever I attempt to load new namespace in to repl :required namespaces can’t be found

triss13:01:14

only seems to be issue with namespaces within the project… dependencies seem fine

triss14:01:09

hmmm. I’ve started a clean figwheel project and all is ok in there

triss14:01:21

apologies this might be a re-frame lein project problem

triss14:01:27

will poke around

thedavidmeister14:01:43

what can i do about this

thedavidmeister14:01:45

(cljs.reader/read-string (pr-str (js-obj 0 "a")))

thedavidmeister14:01:56

triggering TypeError: Cannot read property '0' of null

darwin15:01:26

@thedavidmeister (pr-str (js-obj 0 "a”)) => #js {:0 "a”}, that keywordized number chokes reader (cljs.reader/read-string (pr-str (js-obj “k" "a"))) works

thedavidmeister15:01:58

@darwin yeah, in the real app i'm getting the object from a 3rd party 😞

thedavidmeister15:01:10

i managed to work around with a js->clj call in between 🙂

darwin15:01:38

an alternative would be to use js/JSON.stringify

potetm16:01:48

I've found that keywordizing non-clojure maps to be a pretty bug-ridden exercise.

potetm16:01:12

The bugs will appear in the darndest places.

potetm16:01:26

And the only benefit I've found for doing it is concision. (e.g. (k m) vs (get m k)).

potetm16:01:57

Keywords are useful code constructs, but if they don't fit the data you're dealing with, don't use them.

thedavidmeister16:01:33

@potetm this is what i'm hearing

thedavidmeister16:01:40

something i'll have to chase up another day

thedavidmeister16:01:58

i'm sort of just being forced to refactor due to breaking changes in vendor code

thedavidmeister16:01:09

trying to keep it as "light touch" as possible 🙂

potetm16:01:55

Yeah. That makes sense. Life's messy sometimes 🙂

thedavidmeister16:01:46

all the casing rules for the names of things just had to change of course, and things that were arrays are now objects with numeric indexes too apparently >.<

thedavidmeister16:01:04

cheers for the advice though

david.alfaro20:01:17

Noob here: How can I use Om[Next] to generate AMP tags (i.e. amp-img)?

tyler20:01:02

Does anyone have experience using semantic-ui-react with clojurescript/reagent? I'm trying to figure out how to set up the deps.clj with the minified umd file generated by semantic-ui-react using :module-type :commonjs but I'm having trouble importing basic components like a Buttons. Wondering if anyone else has experimented with this library.

tyler20:01:56

I suppose a better question is does anyone know of any examples of using a commonjs lib bundled to umd from clojurescript?

tcarls20:01:20

@triss, ...any chance you might be using (ns your-ns) to switch interactively? In cljs, you'll want to use (in-ns 'your-ns)

tcarls20:01:09

@triss, ...otherwise the bare definition will overwrite the aliases &c. from a prior ns declaration, making them unavailable.

kokos21:01:44

hm, when i run lein cljsbuild once i get Caused by: clojure.lang.ExceptionInfo: No such namespace:     , could not locate     .cljs,     .cljc, or Closure namespace "    " how would i pin point what the "emtpy" namespace comes from

darwin22:01:41

@kokos tricky, I would start bisecting parts of your project or reverting recent changes

richiardiandrea22:01:49

@kokos if you are desperate 😀 you could try to use tools.namespace, fetch all the ns declarations of your cljs files and either use a simple regex or conform with specs

naddeoa23:01:53

I'm having some issues understanding lein, repls and what I should expect to work in clojurescript. Is this the right place to ask questions or is there a different channel I should head to?

tcarls23:01:57

@naddeoa, there might be a more specific place for some of the individual questions, but there's no reason you can't start here.

naddeoa23:01:43

cool. I'm trying to get set up with spacemacs. I'm normally a Vim user but I had this recommended to me. I made a project with lein new mies which has a bunch of scripts for repls/buliding etc. Those work fine. In order to use the emacs buffer though it looks like I need to use something called nRepl?

naddeoa23:01:49

Does that work for clojurescript?

naddeoa23:01:03

I can't find anything about configuring a project.clj for it

naddeoa23:01:36

I can use lein repl, but it looks a lot like a clojure repl and complains about not finding .clj files and .class files, which smells like Java

tcarls23:01:43

@naddeoa, ...so, nrepl is a protocol; the modern emacs client for that protocol is called CIDER

tcarls23:01:57

(or CIDER.el, rather)

naddeoa23:01:51

interesting. I know that the project's repl script is just this:

(require
  '[cljs.repl :as repl]
  '[cljs.repl.node :as node])

(repl/repl (node/repl-env))

naddeoa23:01:09

Running that gives me a functional repl, but how that is supposed to hook up to nRepl is a mystery to me

tcarls23:01:19

...so, the cljs repl is a different story from the Clojure repl

tcarls23:01:29

the cljs repl is hooked up via a bunch of magic embedded in Figwheel

tcarls23:01:52

which... frankly, I don't personally have figwheel working with CIDER right now, so I'm not a good person to give advice on it (though it certainly can be done).

naddeoa23:01:02

so, whenever I read something I shouldn't assume that it will just work on clojurescript then

naddeoa23:01:36

weird, but I know that the file above does run a repl, and I don't think figwheel is involved

futuro23:01:51

@naddeoa look into piggieback and figwheel

naddeoa23:01:06

two seperate things, or two things that work together?

futuro23:01:29

Piggieback is if you want a cljs repl and figwheel handles live reloading of code in the browser

futuro23:01:38

They can work together

naddeoa23:01:49

ah, so for doing node I can skip figwheel for now?

futuro23:01:00

Also, add the clojure layer to your spacemacs config

futuro23:01:07

Yeah, you should be able to

naddeoa23:01:24

spacemacs has been really nice so far. It prompted me to install the layer when I opened a cljs file

naddeoa23:01:26

which was nice

futuro23:01:36

There's also lumo, which is self-hosted on node, but you can't use nrepl with it yet

naddeoa23:01:43

but all of the commands seem to depend on CIDER

futuro23:01:44

That's sweet

futuro23:01:02

For lumo you'd need to use the inf-clojure package

naddeoa23:01:12

another emacs package?

futuro23:01:20

Yeah, should be

futuro23:01:59

I'm not at my computer atm so I can't double check, but I believe it's by bbatzov, who maintains cider

naddeoa23:01:06

so, do you know what piggieback would be doing that my repl script (part of the meis template) isn't?

futuro23:01:34

Unfortunately no, I haven't experimented with it enough

futuro23:01:59

Though I think cider can start a cljs repl on its own

futuro23:01:20

Alt-x (might be SPC SPC or SPC :) should allow you to start typing in the letters for the command and suggest possible options

futuro23:01:48

So typing in "cider clojurescript" may help you

naddeoa23:01:02

I do see cider-jack-in-clojurescript

naddeoa23:01:10

I assumed jack-in was turn on or something

naddeoa23:01:44

Its just odd to have 4 different ways to start a repl and not have any of them talk about each other online

futuro23:01:35

Yeah, having a guide that talks about all of them would be handy

futuro23:01:13

With cider you don't need to specify the dependencies for starting the repls anymore which is really nice

naddeoa23:01:24

are these problems likely solved for clojure? I'm assuming a lot of this weirdness comes from using clojurescript and readiing guides that don't specify what they support

tcarls23:01:28

Definitely easier with Clojure than ClojureScript these days, yes.

tcarls23:01:40

cider-jack-in will generally just Do The Right Thing with clojure

tcarls23:01:50

telling lein to start up a server, and then connecting to it.

naddeoa23:01:03

Thanks for the help @futuro and @tcarls . I'll see if I can finish this setup.