Fork me on GitHub
#re-frame
<
2016-05-20
>
lewix01:05:59

error I'm getting after running figwheel: https://www.refheap.com/119314

lewix01:05:09

I'm using re-frame template

gadfly36102:05:46

@lewix: can you run lein -v in a terminal and paste back what it says?

lewix02:05:35

Leiningen 2.6.1 on Java 1.8.0_65 Java HotSpot(TM) 64-Bit Server VM

gadfly36102:05:32

damn lol, that looks good

lewix02:05:57

@gadfly361: The error messages are insane

lewix02:05:14

it's really helpful

lewix02:05:55

gadfly361: apparently it didn't compile properly...the file app.js is not present

gadfly36102:05:56

yeah, not arguing there. i just made a new app from scratch - lein new re-frame todomvc and then ran lein figwheel dev and everything worked for me. did you you any profiles when you made your app from the template?

gadfly36102:05:22

figwheel should make that for you when run the command, so is a weird error message to get

lewix02:05:31

I changed two files; db.cljs and views.cljs

lewix02:05:20

@gadfly361: seems like david nolen disagree with me when it comes to error messages

lewix02:05:21

I should probably start from scratch

lewix02:05:26

it's faster than debugging

gadfly36102:05:54

i think everyone has a different tolerance/expectation for error messages, kind of a subjective battle. in my opinion, i am eagerly waiting for them to be improved and i think alex miller is working on that for an upcoming release (if my reddit memory serves)

gadfly36102:05:26

yeah, if you do figure out the error message, could be useful to add here: https://github.com/yogthos/clojure-error-message-catalog

lewix02:05:39

when you start documenting errors, that's when you know there's a problem lol

gadfly36102:05:17

i think it is following Elm's lead which does something similar and their error messages are amazing

lewix02:05:03

I'm really close to change my focus to elm actually. Their error messages are outstanding

gadfly36102:05:43

yeah, Elm is a very good option imo. i plan to explore it more too - curious how the new 0.17 version is going to play out. seems like their community is at the tipping point of getting a lot bigger (relatively speaking)

lewix02:05:05

@gadfly361: we are not expected to run lein figwheel before making any chances, right?

gadfly36102:05:08

@lewix: typically, i start figwheel before making any changes

gadfly36102:05:39

that said, when namespaces are moved around and such, i restart figwheel or wait to start figwheel

fasiha14:05:16

@lewix: also, if stuff just randomly stops working for no apparent reason… I sometimes find restarting figwheel and re-freshing fixes… Stuart Sierra has a talk about pitfalls of auto-update where I learned that this was a known issue.

roberto14:05:16

re error messages, it depends on your experience. More experienced people in an ecosystem prefer verbose stack traces (which are especially valuable in production). For newcomers that can be a problem tho.

lewix14:05:33

@gadfly361: @fasiha that was a bug with fighweel that the maintainer is currently working on

lewix14:05:54

@fasiha: it goes back to what we were talking about yesterday with the error messages

lewix14:05:55

@roberto: it's not a matter of verbosity - it's a matter of quality - the quantity of the error messages doesn't make it good

roberto14:05:13

it all depends

roberto14:05:52

i personally find the error messages ok, but I have to admit I come from a java background, so the stack traces look very familiar

roberto14:05:26

i think there should be two levels of messages tho, just like logging

roberto14:05:42

default: friendly, and we should have the ability to determine how verbose we want it

roberto14:05:05

i wouldn’t like it if they just got rid of stacktraces just to have pretty messages

lewix14:05:22

@roberto: I pointed the error and nobody could figure it out solely based on the stack trace; even though I'm new to the ecosystem most errors messages I came across so far have been bread crumbs. I had to start from scratch before spotting it one line at the time. I later reported it, and apparently it's a bug that has to do with figwheel where an initial exception does not get reported. Again, my point is not about having pretty messages, my point is about putting more emphasis on having relevant error messages

roberto14:05:14

hmmm, the only time I’ve been stomped has been due to dependencies clashes.

lewix14:05:40

@roberto: you're coming from the java world so I empathize 🙂

roberto14:05:59

i probably have a higher tolerance because of my experience with other java libraries. Elasticsearch is particularly deceiving in its error messages

roberto14:05:27

hehehe, funny, I found python and ruby stack traces to be the worse tho.

roberto14:05:57

oh, and I remember angular in its early days

roberto14:05:07

plus, this my show my age, but installing linux on a laptop back in the mid 90s, trying to figure out what the errors meant (if we got the chance to see any) was lots of fun

richiardiandrea15:05:07

@roberto: oh I shed a tear reading this, I started with RedHat 6 or 7 I think. Hours spent staring at the monitor or waiting that someone was answering on a forum...

lewix15:05:11

...and our ancestors didn't have planes,cars, and cell phones

roberto15:05:03

our descendants won’t have those things, the way things are going….

lewix15:05:29

Moore's law

lwhorton16:05:13

Heya guys.. I’m poking around the clojurians slack log and other reframe sources, but I dont see a clear solution for how to handle this problem: many features depend on a websocket connection, how do you hook each feature into a single connection once that connection is established? I can’t have a bunch of listeners wired up to [:connection-established], for example, because of the 1-1 nature of handlers/events.

lwhorton16:05:46

It seems like a bad idea to have features subscribe to the db’s :is-connected flag (or worse, put the connection into the db), and then invoke some sort of subscriber once the is-connected appears. Or maybe that’s the idiomatic way to do it?

lwhorton16:05:53

I’m also hesitant to just top-level-invoke some function that registers to another global subscribers [] or something like that, since top-level is supposed to be reserved for function names, and essentially only that.

lwhorton16:05:34

The more I think about it, the more this seems like a more abstract question: how do you coordinate bootstrapping or time-sensitive ordering dependencies for things that don’t fit into the normal ‘reactive flow’ of event -> handler -> sub -> db

richiardiandrea16:05:59

@lwhorton: maybe I did not understand very well but I will try... can't you dispatch an event when your websocket connects/receives something?

richiardiandrea16:05:32

you init at the beginning but then what it does is just to dispatch that's it

lwhorton16:05:48

I can, but I guess that means my single handler for ‘connection made’ has to then “know” about every feature in the app that wants to use websockets.

lwhorton16:05:58

Top-down versus hooking-up— it’s not unthinkable, it would just be nicer decoupling. I may have to look at something like mount and just stay outside of reframe for this part.

richiardiandrea16:05:33

uhm yes true, you would need to add a big case in the handler

richiardiandrea16:05:55

maybe in this case a core.async channel would decouple better I guess

fasiha18:05:45

@lwhorton: here's how I do it: in app.db/default-db map I have a slot :ws-socket nil. In app.handlers I have (and everyone who uses the lein-re-frame template should have) a handler for :initialize-db. That's where I initialize the websocket (and send a couple of XHRs). Specifically I have something like:

(defn make-websocket [url on-message-fn]
  (let [sock (js/WebSocket. url)]
    (set! (.-onmessage sock) on-message-fn)
    sock))
; ... then in the :initialize-db handler:
   (-> db/default-db
       (assoc :ws-socket (make-websocket
                           (str "")
                           #(r/dispatch [:websocket-message (-> % .-data)])))
; ...

fasiha18:05:35

So that creates a websocket object with a handler that just dispatches another handler, and sticks the websocket object in in app-db and forgets about it

fasiha18:05:06

In my app, the server only sends data to the client, so whenever that happens, my :websocket-message handler deals with the data.

fasiha18:05:11

People talk warmly about using sente in situations like this—generally I like to do things at least once 'manually' without a library (this is my first time using websocket), so I know what's going on, but the basic idea is the same: do these one-time async tasks in the :initialize-db handler.

lwhorton18:05:29

I see. thanks @fasiha - i looked at sente but unfortunately I dont have complete say over the server side.. meaning I got stuck with crossbar and wamp

fasiha18:05:13

I haven't done any client-to-server data movement, but I'd think that I'd start by making a single handler that sent data to the server (and which talks the websocket API), and other handlers/subscriptions dispatch that with whatever they want to send. It does require each part of the app that needs websocket to invoke that one handler, and might be too much complecting, but that's how I'd start

lwhorton18:05:31

just for some contrast, I implemented a solution with mount that is fairly straightforward - a consumer registers a defstate init :start do-init and takes a dependency on a websocket defstate conn :start make-conn

lwhorton18:05:02

essentially keeps reframe out of it, which I think is a cleaner solution— use whatever you want on the fringes, and the touch-point between the ws and reframe is a simple handler that dispatches

lwhorton18:05:42

we’ll see what other implications arise, but for now I think i like it better than involving the dispatch system and app db

fasiha18:05:04

Ah, interesting! I did mountify my code a little while ago too, I didn't realize one could use it that way

underplank19:05:20

Hey all. I’ve got a function that makes a http request using cljs-http. Once I have the response I (dispatch) it which will eventually handle errors and success and put it into the atom. I want to test this function, but im not sure how to block until the result gets to the atom so that I can check the results. Does anybody have some pointers to a test for this?

underplank19:05:50

I thought I could put the assertion in a go block but that makes the test async which could cause some issues I guess.

underplank19:05:01

mccraigmccraig: I dont think that solves the fact that the http request is async. It solves the async dispatch. I’ve found the async test macro that might help.

mccraigmccraig19:05:07

oh, i see - you will have to use a core.async channel, or a promise then... i tend to prefer promises for non-streaming operations like http requests

mccraigmccraig19:05:15

i've been using http://funcool.github.io/promesa/latest/ for promises and am very happy with it

nberger22:05:12

There's also cljs.test/async for async testing