Fork me on GitHub
#hoplon
<
2016-04-15
>
jouerose09:04:27

does this display anything for you in the hlisp ?

jouerose09:04:35

should it or not ? thanks

jouerose09:04:10

btw, i actually added :type "button" because the html5 reference i have says it must have a :type

jumblerg10:04:10

@jouerose: it does, although if you want “hello world” to appear on the button itself, you need to do (button :type "button" :name "button-name" "hello world”). the value attribute in html is for use with submission mechanism of the enclosing form, i think.

jouerose10:04:40

@jumblerg: thanks very much

jouerose10:04:00

@jumblerg: meanwhile i had just gone with an (input :type "button" :value "button-value") and "button-value" appeard on the button

jumblerg10:04:59

yeah, an input of type button is a different thing for use within an form

jouerose10:04:11

by the way, there is something i have been wondering. why instead of js interop don't we have functions such as (get-element-by-id elem-id) ?

jumblerg10:04:01

well, i’d argue that when building spas, esp with hoplon, we should avoid selectors entirely.

jouerose10:04:25

interesting. why ?

jumblerg10:04:50

there’s no reason to go fishing around in the dom matching on strings when we can just bind to variables (who knows what you might scoop up in a global tag soup). this convention is madness, really, when you stop to think about it.

jumblerg10:04:22

in hoplon, you have references to the elements in your code before they’re added to the dom. just work with those instead. much simpler. more performant. and you’ll actually get an error when something bad happens.

jouerose10:04:08

please give me a simple code example

jumblerg11:04:28

no worries. i think you’ll find this to be a far more sensible way of doing things once you become accustomed to it.

jumblerg11:04:41

if you’re being handed an html document from a server, and you need to mutate it afterwards, then you might need a selector to pluck the node out of it you want to alter. but when you’re building an spa, you already have those elements, so you can reference them using vars/variables instead.

jouerose12:04:13

what is the usual go-to library/form for http requests in clojurescript ?

thedavidmeister12:04:55

@micha: i managed to reproduce that bug from the other night in a minimal setup

thedavidmeister12:04:01

just writing a test now to demo it

micha12:04:16

@thedavidmeister: it's so awesome having test cases

micha12:04:27

this is like a million times better now

micha12:04:41

thanks for all the hard work to make that happen

thedavidmeister12:04:54

it’s hard to share/fix bugs without some basic tests

jouerose12:04:33

@micha hi. hope all is good. please let me know. if i do (.log js/console "something") , where does "something" appear ?

micha12:04:03

@jouerose: in the javascript console of your browser dev tools

micha12:04:23

you can also do like this:

micha12:04:33

(prn {:a 1})

micha12:04:55

it will show up in the same place, the difference being that the clojure data is printed in a way that you can see it

levitanong12:04:46

@jouerose: and @micha, if I may butt in, I’ve found that (.log js/console) is more useful for printing js data structures (like if you’re working with external js libraries like d3) and println is more for clojure data

jouerose12:04:14

@levitanong: thanks for the hint

micha12:04:26

@levitanong: @jouerose i also made a little collection of macros for logging things: https://github.com/adzerk-oss/cljs-console

thedavidmeister12:04:39

i only just realised today that I can do this (defn prnr [v] (prn v) v)

thedavidmeister12:04:48

and then not have to restructure my code every time i debug >.<

jouerose12:04:52

@micha @levitanong what would be your go-to method/way for http request in clojurescript if you are not using castra ?

micha12:04:59

that would be my spy-> macro

jouerose12:04:10

@micha will go check this out. thanks

thedavidmeister12:04:09

anyway, i g2g for a bit

micha12:04:28

@jouerose: you can use the jQuery ajax stuff, or any other XHR library you like

thedavidmeister12:04:10

if someone could think of a way that :value could tell the difference between two different cells with the same value, while i’m gone, that would be just amazing 😛

micha12:04:30

i will investigate! simple_smile

jouerose12:04:04

@micha thanks. will try cljs-ajax

levitanong12:04:29

spy-> is what i’ve been looking for for a long time

jouerose12:04:44

@micha any plan to insert cljs-console in hoplon ?

micha12:04:46

@jouerose: if you're not sure which one you like i would recommend using jQuery because it's the best documented of any of them, and it's the best tested

micha12:04:15

so you are unlikely to run into browser compatibility bugs, and you can look on stack overflow for answers to any question you could ever imagine

micha12:04:57

jQuery is running on about 70% of all webistes on the internet, vs how many for cljs-ajax?

micha12:04:42

no plans to bundle cljs-console with hoplon currently, but we could if there is interest

jouerose12:04:09

@micha if it may encourage the bundling of cljs-console, i think the less we see/have to do interop, the better.

jouerose12:04:45

@micha no idea for cljs-ajax coverage. would you recommend "jayq" for jquery in clojurescript ?

micha12:04:12

no, i'd just use jquery via the cljs interop

jouerose12:04:33

any particular reason ?

micha12:04:38

the various wrappers don't really add anything

micha12:04:57

except another layer to debug and understand

micha13:04:19

they just define functions with the same name as the jquery methods

micha13:04:31

but then how do they work with plugins?

micha13:04:42

do you make a wrapper for every plugin?

micha13:04:47

seems like overkill

micha13:04:04

the only benefit you get is automatic conversion of clojure data to js objects

micha13:04:13

but that's a lossy algorithm

micha13:04:27

so you need to now understand the tradeoffs they make there

jouerose13:04:38

i see. thanks

jumblerg13:04:49

@jouerose: here’s a snippet i wrote earlier this am you can use to get started:

(defc projects [])

(defn data [resp]
  (-> (.parse js/JSON resp)
      (js->clj :keywordize-keys true)))

(defn load-projects! [] (.get js/jQuery projects-url #(reset! projects (data %))))

micha13:04:40

@jumblerg: why not use the (.getJSON js/jQuery project-url ...)?

micha13:04:19

that does all the stuff with setting Accepts and ContentType headers, parsing response body, etc

jumblerg13:04:41

@micha: because i didn’t know about that fn simple_smile

jumblerg13:04:02

so i am now!

jouerose13:04:39

@micha cljs-ajax wraps goog.net.XhrIo or js/XmlHttpRequest .

jouerose13:04:54

from the readme.

jouerose13:04:27

@micha do you think it could cover less ground than jquery ?

micha13:04:58

it's just that google closure library has .005% use, while jQuery has 70%

micha13:04:17

so finding quick answers to questions is way harder

micha13:04:31

and bugs are more likely to be encountered by you

micha13:04:06

i like using jQuery for the cross-browser standardization layer just because any bugs will have been worked out already

micha13:04:25

whereas the google closure stuff is really only used by google, and not even in their main applications

micha13:04:43

so they won't see the bugs that you are likely to encounter

micha14:04:25

also using google closure is not free in cljs

micha14:04:45

if you use a google closure API that code will be included in your application

micha14:04:51

and if you don't use it it won't

micha14:04:59

it's a common misconception about cljs

micha14:04:07

that it already includes all of google closure

micha14:04:11

but that's not the case

micha14:04:17

it only includes the parts you use

fasiha14:04:21

Y0 @micha, @jouerose mentioned on #C03S1L9DN that you had made some interesting comments about goog.net.XhrIo here so I'm check them out 😛

fasiha14:04:46

I'm a huge n00b so no worries 😄

micha14:04:03

just my humble opinion, please take with grains of salt

fasiha14:04:21

Something's wrong with the internet today, people are being humble?! 😄 😛

fasiha14:04:34

Or is that just the awesome Clojure community ❤️

fasiha14:04:25

I just want to confirm: http://goog.net should take care of all the cross-browser issues for me, like jQuery right?

micha14:04:05

well in theory yes

micha14:04:21

but i've run into problems with goog closure before

micha14:04:39

and i just don't have time to maintain my own set of workarounds for different browsers

micha14:04:47

to wrap the goog stuff with

micha14:04:53

jQuery is guaranteed to work

micha14:04:04

it's used by most websites on the internet

micha14:04:20

so for the simple things i need it's a done deal

micha14:04:30

also googling for weird edge cases is really easy

micha14:04:52

because out of the millions of sites that use jQuery someone will have already run into the issue and posted it on stack overflow

micha14:04:27

like i ran into issues doing something as simple as setting element attributes with goog closure

fasiha14:04:47

Gotcha, I guess I took it without question that Google Closure's libraries were solid because a number of ClojureScript people have spoken highly of the Closure compiler. I will definitely start considering individual projects for pieces that I'd otherwise use goog.* (like cljs-ajax).

micha14:04:03

the closure compiler is a different thing, though

fasiha14:04:17

Right, I combined the two in my mind

micha14:04:22

for DOM compatibility layer i think wide adoption is pretty useful

fasiha14:04:34

I use React/re-frame for DOM so 😛

micha14:04:07

yeah that's getting wider adoption

micha14:04:13

but it's still a tiny minority

micha14:04:33

for me separation of DOM compatibility from the framework is key

micha14:04:56

i just don't have the time to guarantee cross-browser compatibility myself

micha14:04:19

and jQuery mostly Just Works (tm)

fasiha14:04:34

Right, nobody wants to handle cross-browser stuff. I personally most likely won't be using jQuery but I will definitely look at reusing HTML5 and shims instead of relying on goog.* (e.g., before ClojureScript, I would use a fetch shim): https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

fasiha14:04:51

So when I google "clojurescript web server", hoping for something like Ring or Express.js except in cljs for Node, hoplon comes up, but hoplon isn't quite Ring/Express right? It seems more than that

alandipert14:04:42

@fasiha: yeah hoplon isn't serverside cljs really

fasiha14:04:06

Is there anything in that space?

alandipert14:04:27

i know i've seen things, but don't know any offhand

fasiha14:04:55

I'm looking for options because I wrote this nice Clojure backend to talk to a ClojureScript frontend to run on the Raspberry Pi. But JVM & lein run takes 2 minutes to start, whereas node.js starts in a second. So luckily I had prototyped most of the backend functionality in Node so I was planning on using a Node server, but thought to ask if Cljs+Node was an established thing or still experimental.

jumblerg14:04:07

@fasiha: i remember seeing this experiment a while back https://github.com/seabre/matchcolor

alandipert14:04:30

@fasiha: cool, yeah. hoplon kind of relates to the server side in the sense that it can work with any backend. we built it originally on top of a php backend, and at this job it's on a clojure + mssql backend

fasiha15:04:18

Thanks @jumblerg between that and @bhauman's https://gist.github.com/bhauman/c63123a5c655d77c3e7f I think I can take a shot at it. Maybe there's not much chatter about express+cljs because it's so easy.

jamieorc15:04:53

@micha where does one find this spy-> macro?

jumblerg15:04:21

just got asked by someone here at work if there was a figwheel task for boot. if the perpetual recurrence of this word has taught me anything, it is that boot-reload needs a catchier name. 😬

jumblerg15:04:11

ideally, something that completely obscures the semantics of the task in favor of the mysterious and magical.

micha15:04:52

figwheel is like boot-cljs + boot-cljs-repl + boot-reload + watch

micha15:04:04

it works great, i'm not knocking it

micha15:04:22

one day we will move boot-reload to use the figwheel client library

micha15:04:10

to avoid duplicated effort

jumblerg15:04:37

it does, i’m simply fascinated by how frequently this word keeps coming up.

micha15:04:58

it's a cool name, too

jumblerg15:04:59

people who have never written a line of clojure before start by asking me about figwheel

micha15:04:24

it's way better than any of the things i've seen in the javascript world

micha15:04:43

so i'm not surprised that people heard about clojurescirpt via figwheel

micha15:04:06

pretty much the gold standard for live coding of web app stuff

jamieorc15:04:23

it’s quite nice

jamieorc15:04:54

any suggestions for configuring Idea/Cursive for Boot and Hoplon files? I see that Colin intends to support them, but hasn’t gotten there yet

jumblerg15:04:44

does figwheel carry any semantics that the current boot cljs pipeline lacks?

raywillig15:04:22

can someone build boot-hype so we have a feature complete pipeline?

micha15:04:03

@jumblerg: i don't know of any, but I imagine there are differences in functionality on both ends

alandipert15:04:40

i feel like figwheel is more aggressive about macro reloading or something

alandipert15:04:53

its been like a year since i compared them myself

micha15:04:09

that was addressed recently i believe (like in the past 8 months)

alandipert15:04:57

@jamieorc: re: cursive, there is stuff in the boot wiki about emitting project.clj from boot, which lets cursive at least see deps

jamieorc15:04:40

@alandipert: thanks. I set that up, but still not seeing deps. I’ll have to see if I missed something.

jamieorc15:04:12

the .hl files are full of “can’t be resolved"

alandipert15:04:41

hm, yeah. i bet cursive doesn't know about page

jumblerg15:04:43

@jamieorc: i think @symbit has this process down, might be worthwhile to ping him direct, he could probably get you started.

jouerose16:04:22

hi all. is the use of the "(do ...)" form, a hint that may be i am not doing something well , or at least in the clojure/functional way .

micha16:04:37

@jouerose: do is a super useful thing that Lisp has, definitely not bad to use it

micha16:04:57

usually it indicates that side effects are happening

micha16:04:21

(because only the last expression's value is returned, not the preceeding ones)

micha16:04:08

i think with Lisp there are no features that indicate bad code when you use them

micha16:04:47

like do is a crucial construct. that's how lisp eliminates "statements" from the language

micha16:04:09

every form in lisp is an expression that evaluates to a value

micha16:04:14

super awesome

alandipert18:04:47

hey grant, welcome 👋

grant18:04:20

Thanks Alan.

leontalbot19:04:48

@jumblerg: I now see the dashboard. I am now ready to fire missile on flying @micha 😉

leontalbot19:04:58

@jumblerg: So i'm in, but when I click on the red button, I get

core.cljs:264 Uncaught Error: No protocol method IStack.-pop defined for type cljs.core/PersistentArrayMap: {#uuid "2631d90a-eed4-4626-ad07-c4eb3c46b62c" {:fuze :vis, :warhead :nuke}, #uuid "caba4fe2-1589-4565-8e1c-d40a1fd29edb" {:fuze :vis, :warhead :nuke}}

leontalbot19:04:07

this is where the problem happens (in the swap part)

(u/button hoplon.ui/+danger-button+  :w ["100%" sm 200] :h 50 :click #(swap! missiles pop) "Fire Missile")

leontalbot20:04:08

@jumblerg: about routing, I would need to put more than one (u/window ...) per page, I guess this is possible... Though actually, I get to see the two windows at the same time (side by side), whatever routing I pick...

leontalbot20:04:23

Also, when I make a change, I see the new resulting windows is added to the right, but the old one stays there (until I hit browser's refresh button)

jumblerg20:04:06

yeah, none of the controls are implemented yet. it is pretty straightforward from there though.

leontalbot20:04:29

regarding multiple window rendering, do you get the same behavior?

jumblerg20:04:42

the layout is the thing

jumblerg20:04:35

otg, but file a bug with a screenshot

leontalbot20:04:59

will do, thanks man!

jumblerg20:04:02

oh, i think the two artifacts are stepping on each other in the build process; be back behind my laptop in 1/2 hour or so.

jumblerg20:04:02

@leontalbot: wrt multiple windows, i’ve never tried that, and no, that’s not the recommended approach for routing. you should have one window per artifact; the window component is merely your interface to the browser window. apologies, i misunderstood what you were doing earlier.

leontalbot20:04:35

@jumblerg: Still have the problem when I change something in the code though

jumblerg20:04:13

there are callbacks that fire on the window component when the route changes in the browser. similarly, you attach a cell to the query and route attributes that sets the path and query string in the browser.

jumblerg20:04:43

with only one window present?

jumblerg20:04:28

the screenshot appears to show the TEST from your second window you added to the same file.

leontalbot21:04:26

@jumblerg: yes, even with one window i get this when changing smth in the code:

jumblerg21:04:51

@leontalbot try pulling the responsive-layout-attributes branch of hoplon now and boot build-jar

leontalbot21:04:43

@jumblerg: regarding multiple-window per page, this would be really convenient for multiple pages website.

leontalbot21:04:02

Because of the compilation time "issue":

leontalbot21:04:53

with hoplon/ui offering this out of the box with be a great win.

leontalbot21:04:21

this might be really naive though. I am just dreaming here

jumblerg21:04:38

i’ll think about it. it is page that is responsible for creating the artifact atm; the window component basically creates the html, head, and body elements for you in addition to creating interfaces to the browser.

leontalbot21:04:26

gotta go, will test tonight

jumblerg21:04:20

as best i can tell, hoplon already has support for multi-pages/“artifacts" per “site" such a thing is necessary. via the page declaration you can create as many pages as you like.

jumblerg21:04:34

if you’re loading different pages, you need to reload whatever state each page requires back into memory from somewhere, most likely the server or maybe local storage. the advantage of an spa is that you can share state already in memory across all your views. it would be something of a shame to compromise the architecture of an application because of a development time tooling issue.

leontalbot22:04:56

@jumblerg: True. I think the main issue with multiple pages is compilation time. Multiple pages slows down reload and first load... so we get to a point we need to go with SPA. So how would work h/ui with SPA, only one window with a cell at :route ?

leontalbot22:04:55

Is that where you want to go?

leontalbot22:04:30

"it would be something of a shame to compromise the architecture of an application because of a development time tooling issue." Ok, gotcha

jumblerg22:04:05

i'll share some example code with you offline