This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-06-04
Channels
@mikethompson: Re googleability, that's a good point. Can one write plugins for slack? Their page on integrations doesn't make it clear, there's a reference about having to get in touch if one wants to integrate.
@ricardo: essentially, logbot will export logs as static html splitted by days and channels and exposed to google
Sounds good @ul. For what it's worth, the URL on @logbot's description 404s right now, in case it's not a known issue.
yes, i'm working on export feature and basic template right now. i was eager to start logging asap to capture more messages before any other feature is ready
This is a cool demo of Sean Grove including live source code in his Figwheel web UI: https://www.youtube.com/watch?v=Q5vh1Xj-xM4
What astounds me is that you think you have a good feel for what is possible in a given language, and then Sean comes along with something like this and pushes on that boundary. Things like that make you stop and take pause
Wow that is pretty awesome.
when calling instance methods do I have to import/require the namespace where the instance method is defined?
nevermind
was misled by my own human error :satisfied:
@martinklepsch: Closure namespaces have to be required (or imported) just like ClojureScript ones.
@dnolen: If I do (.getQueryData (uri/parse js/location))
with goog.uri :as uri
and then call .get
on it it works fine without explicitly importing goog.Uri.QueryData
— is that safe to expect?
@dnolen: sems it does http://google.github.io/closure-library/api/source/closure/goog/uri/uri.js.src.html#l32
Really cool stuff from Sean Grove, I’m sure that trick will come in handy some time!
aw yeah ClojureScript, Om, Clojure, Datomic https://precursorapp.com
wow that is responsive
@erichmond: what does DOCCS mean?
haha, my horrible attempt at acronym-izing the Datomic Om Clojure ClojureScript stack
Yeah, I'll shut up, I've written nothing of consequence this entire morning. I blame it on my lack of sleep. heh.
is there any known practical use of Hoplon? http://hoplon.io it's impressed me, but i guess i can get something wrong as a beginner. it seems not so popular.
@erichmond: DHCCS sounds even worse though )
@jellea: oh, hello. glad to see you here. will you answer me after the third e-mail in a row by the way? )
@guy_do_or_die: i'm also completed a small project with Hoplon
@micha @ul cool. is there public code? would love to look at it if possible. thanks in advance.
guy_do_or_die: lots of examples here https://github.com/tailrecursion/hoplon-demos
guy_do_or_die: we're in the process of releasing new versions that work with boot 2.0.0
oh, now i see how come that you use it )
sure i have this resource in mind
guy_do_or_die: here is an application you can see https://github.com/exicon/homepage
@guy_do_or_die: https://bitbucket.org/ul/runes24 , not sure if it is idiomatic Hoplon, but nevertheless
@ui i'm Russian actually ;
So I'm really liking the concepts in re-frame, but I'm having just a bit of trouble getting off the starting line ...
I think I found it. Gotten f*cked by the "(get atom key) returns nil" Clojure wierdness. I left out an @.
FYI:
(register-sub :current-page
(fn [db _]
(reaction (:current-page @db)))) ; correct
vs.
(register-sub :current-page
(fn [db _]
(reaction (:current-page db)))) ; incorrect, always nil
Just started yesterday. Not much to show yet. Alas, I'm working on something proprietary so I can't share.
There's a simple example, and a impl of To Do. Also, there's re-com (components for re-frame)'s demo: http://re-demo.s3-website-ap-southeast-2.amazonaws.com/#/time
I'm playing around with re-frame and re-com. I haven't gotten very far with it, but the code is out there, such as it is: https://github.com/pkobrien/reactionary
As much as I like re-frame I also feel like there is avoidable boilerplate code, especially when it comes to maintaining the state (aka, app-db). I like avoiding boilerplate code. I'm still exploring options in this area.
I'm having an issue with re-frame vs. figwheel. Because of figwheel, I'd expect that when I change a component function, I see the change immediately. But that's not the case.
Currently, I'm storing my page component function inside the app-db:
(defn home-page
[]
(fn []
[nav-border
{:title "Welcome to the MIX Merchant Portal"}
[:div
[:div [:a {:href "#/about"} "show about"]]
[:div [:a {:href "#/credits"} "show credits"]]]]))
(secretary/defroute "/" []
(dispatch [:set-current-page home-page]))
(defn mount-root []
(reagent/render [current-page-view] (.getElementById js/document "app")))
Where current-page-view is:
(defn current-page-view
[]
(let [current-page (subscribe [:current-page])]
(fn []
(if-let [page @current-page]
[page]
[nav-border {:title "Loading ..."} nil]))))
I believe the issue is that current-page-view component is not "dirty" because :current-page of app-db is unchanged ... the prior version of the home-page function before the figwheel reload.
Short of turning current-page-view into a case statement (or maybe utilizing a defmethod) I'm not sure how to convince the stack to re-render when home-page changes.@hlship: when you use the component are you using it with [home-page]
or (home-page)
? should use the []
http://reagent-project.github.io/news/news050.html — see the note in the end
hlship: I had a similar issue locally (we were using secretary to dispatch and load the page into reagent, the solution was to use :on-jsload to directly invoke secretary)
@ul I believe that's already happening (inside my dev.clj), and even a REPL invocation of (mount-root) doesn't pick up the change.
following along with O’Reilly’s Clojurescript tutorial and using mies template .. is “compile_cljsc” old? its not in my scripts directory
@noisesmith: I'll look at the secretary api.
@clojuregeek: sorry yeah I don’t actually have time to keep up with all my various OSS projects. compile_cljsc
is really not necessary anymore, AOTed ClojureScript JAR is available
@clojuregeek: have you looked at the Quick Start?
hlship: are you using secretary already?
@dnolen: in the past I have looked at it. I just got the videos so I was wanting to follow along.. so meis is not best to use?
yes, it was part of the template from "lein new reagent". Just looking for a function that says "redispatch the current URL".
hlship: what I did was (secretary/dispatch! (get-myurl)) where get-my-url is custom to my project (since this is a SPA and we dispatch only on fragment, and the main part of the URI never changes)
@clojuregeek: mies
just out of date now. But you should be able to proceed without compile_cljsc
. compile_cljsc
was just an optimization thing so the project would compile faster.
@dnolen: ok, thanks
@clojuregeek: do you have a link to the ClojureScript video you’re talking about?
@clojuregeek: yeah ok I’m not familiar with those at all. Let me know how it goes, you should be able to work around the changes to mies.
@dnolen: thanks
@noisesmith: This is what I've come up with, replacing some of the template code, and it seems to work:
;; Should not be defined until all routes are defined.
(defonce history
(doto (History.)
(events/listen
EventType/NAVIGATE
(fn [event]
(secretary/dispatch! (.-token event))))
(.setEnabled true)))
;; (re-)initialize app
;; This is called on after each JavaScript reload (via Figswheel).
;; see fan.merchant-portal.dev
(defn mount-root []
(reagent/render [current-page-view] (.getElementById js/document "app"))
;; This is only really needed on a reload of the page, it forces a new dispatch
;; based on the URI. This may become a problem if we start doing any other kind
;; of initialization on page transition, but will do for now.
(secretary/dispatch! (.getToken history)))
oh yeah, using history, that's smart
I complected things by looking up the thing my secretary router uses manually, I should probably switch to using history itself too
But see my note, I'm thinking that a multimethod approach may work better ... if that'll work well with reagent.
hlship: in my app it's a strong rule that all state specific to a page must be invoked by secretary - because bookmarking breaks otherwise
hlship: so invoking secretary is actually the way to force things to stay sane
if bookmarking isn't a priority, you do need to look out for other future gotchas, of course
What I'm concerned about is this likely scenario. A defroute changes the page AND does some other initialization of the app-db, say setting a property to a default value, maybe something like a search filter. As a developer you work with the page for a bit, and change that property. You then change some code and the browser refreshes ... but the defroute resets that value back to default on you. Not the end of the world, but frustrating.
hlship: yeah, this fits into what I was saying about bookmarkability - anything which would be a pain in the ass to recreate state wise should be reproducible from the uri
Maybe it'll all work out, as there will be one route/URI for initalizing the page, but as I manipulate the property, that will be a different URI.
or that's my idealistic vision at the early stage of this app at least
@noisesmith: I've done it like that too. More or less rest api-ish urls on the client
borkdude: right, except everything is in the fragment (after the #) so no page-loads are implied by "navigation"
@noisesmith: right, I use # too, but mostly because I haven't yet explored what you can do with pushstate. I don't use server side rendering either.
my first instinct would be to treat server side rendering like a form of cache / optimization
eg. it shouldn't force anything else to change behavior, even if it has to get a little messy in its own logic
chipf0rk: it defeats the HTTP model: the path refers to a document, not to arguments passed to a cgi script or whatever
but it works great if you have the server rendering the same thing (what people call isomorphic), right
I think pushState is powerful enough for bad designs to do stupid things. So many ways to make reload, or bookmarking, or the back button break.
if you show me an application using it, i'm pretty confident that i could remove swathes of code by switching it to use uri fragments instead
the url of the single page app (like http://foo.com/index.html or whatever), that's like the maven coordinates of a JAR
it wouldn't make sense to deploy a JAR to maven for every permutation of comand line arguments
right, it breaks some very reasonable expectations about what in the url bar represents a document from the server, and what represents reloadable js state
a big problem arises though if you just use hashbang for everything. i'm unsure about what combination works best here, for a SPA
in my idealistic opinion, what the hashbang describes should only be like a component's localState in React. that implies a lot of isomorphic capability that I myself haven't been building into my applications, but that's how it should be, right?
you're not describing anything at all with your path, because it's empty. you put the entire rendering, fetching data etc. on the shoulders of the browser and js, right?
you're always initially just sending a request that says "hey, give me a description of the entire application" (the js code) and the server hands to you a bare skeleton that the browser has to fetch the data for and fill up all by itself. i'm not sure if anything else is possible with hashbangs because they're not part of the request at all, technically
"you're not describing anything at all with your path, because it's empty." can you explain that? I don't get it
i think google had some technique that it required you using to make it crawl your spas anyways
I have been thinking about a public site as a hobby project though and I'm divided between multipage or SPA.
@micha: what do you do specifically to prevent this? i haven't looked into hoplon so I didn't really understand your description
chipf0rk: i never do serverside rendering of html for a SPA, except for the ajax crawling stuff, which is sent in the query string
the backend is just an RPC thing communicating with the frontend via JSON (cljsjs, transit, whatever)
well it's a technique, it's not an all-encompassing paradigm. i think being able to pre-render most things on the server is great
chipf0rk: search engines render js now, and for years now they've supported crawling single page apps
i have a ring middleware i use on the server that can render the escaped_fragment ajax crawling stuff in phantomjs or htmlunit
yeah it makes no sense to want to support luddites who turn off JS in your single page app
it's not about people that disabled JS, i don't know of anyone who actually does that
so if you want a CMS for example, you can use any number of things, like wordpress or whatever
you're saying that SPA == complex application. it's by now a technique for many websites that i wouldn't really consider "applications"
the work i do always inevitable ends up being divided into three logical parts: brochure, client, and admin
that's a false dichotomy, you don't have to have either a) a web project that works great as static content without the benefits of SPAs and b) one that only works as a sort of glorified REST client
i dunno, the sacrifices you need to make to support serverside rendering like php does it completely destroys the elegance of the SPA
if i need a brochure site for a real business i can just hire someone to knock out a jekyll site
@borkdude: Not sure, whatever fulfills "I read through it and understand it. I read code that uses it and understand it"
@rauh: but I know what you mean. I tried Reagent after Om and found it easier to use and also read the code.
@borkdude: yeah that was kind of my point (reg reagent) but I really want to switch to OM the more I think about it.
it's the same thing with leiningen vs boot maybe: leiningen is easier to set up and things work out of the box, but the more I think about boot, the more it makes sense to me
I dont think boot vs lein is offtopic here. But I had a terrible first experience with boot+cljs a few months ago so I wont give it another look for a year or so.
I recently tried boot+cljs and it was not fun. I picked some template someone suggested to me that was for "developing cljs apps" and it was just a mess. Couldn't get macros to compile, I needed to restart boot whenever I changed. Spent forever reading boot source code trying to figure stuff out. Finally gave up and went back to figwheel.
I had some problems too setting it up, but when I returned to leiningen and found myself doing a lein clean while in the other window lein cljsbuild was running... I was enlightened.
Om Next is as much about disseminating the ideas as it about the actual deliverable, same as early Om releases
@dnolen: Yeah but /maybe/ you could provide some sugar namespace that makes it a /tiny/ bit more like it? 😉
@dnolen: My general assumption about Om Next from things you've said so far is that it's an extension of the Facebook React/Flux/Relay/GraphQL ideas - is that somewhat accurate?
@borkdude: yeah I took a look but didn't consider it for some reason. My next goal is def. to do some major OM instead of reagent.
my major pain with om was that I had to think which level of the app-state I would give to the child components and restructure things all the time to make it fit - I guess that problem has been solved by ref-cursors
I dunno, I feel like Om suffers from what a lot of Clojure libs suffer from, a lack of documentation? Or maybe it's there and it's well hidden? I think David does a better job than most library maintainers with cljs and om, but with both I still found a lot of resources that help me get started at the very bare minimum, but left me high and dry once I wanted to do something more involved? So I switched to reagent just because it's so basic I don't really even need to read anything to get it...
I think it's more illustrative of how young our language and communities are, but, still.
@borkdude: yeah that problem is addressed simply by having the notion of a Store. So if DataScript makes more sense to you just use that.
@mystery: at least @dnolen aptly replies either in IRC or here - he always helped me when I was stuck, kudos for that.
Om Next provides more guidance for structure, but there are plenty of hard problems there are no good answers for
it seemed like reagent had better docs for getting up and running
I ended up skipping passing cursors around, just used ref-cursors for notifications when the data changes and it is time to redraw the component.
like tiny introduction to what it does, and a code example
@mystery: I wasn’t assuming you were. Just saying that Om just doesn’t care that much about how you go about building your app.
but i can see where Om might be more robust
I’ve used enough things to know the dangers of assuming you know what people want to build.
@mystery: right Om isn’t not necessarily a beginner friendly thing, but it’s kind of non-goal.
i came to all of it from basically no CLJS background, so i favored that which got me something quick. which is not to say that is the best, just throwing out my experience
I didn't use much clojurescript before I used Om or Reagent. I got sold on cljs by those libraries.
@jarofghosts: right, so I don’t know what to do about that. I wrote this after doing this stuff for 10 years. Sadly mass telepathy isn’t a thing yet 😄
i was working on a front-end for a clojure project and it just seemed natural to use cljs
@dnolen: yeah, definitely; i am not even attempting to say that it is a fault of any kind
in fact I have more experience now with cljs than native javascript, which is almost zero
i am just trying to reason about what might make someone choose one over the other for X amount of time
i chose reagent because it was easiest to learn alongside literally everything else
which is not to say that i will continue to use it forever
or that i think it is inherently "better" or etc etc
honestly Om is what sparked my interest in CLJS
a while ago
i just never had an opportunity to actually do anything in it
Reagent seems rocking to me. I hope that the Om Next ideas flow through all the other badass ClojureScript React bindings.
@mystery: yep, that’s not going to change either. In fact in the next version components are literally just React components with default methods. No reify
indirection.
Do the Om docs point people towards the React docs? That might help some people out (my dumb face didn't realize I should do that for a while despite having seen @dnolen talk about how Om was meant to be close to React in real life).
@dnolen: Have you looked at what has been going on with re-frame at all in Reagent? It's pretty awesome too but is missing the Relay-ish story that I'm hoping Om Next brings.
😛 Yeah I think it was the lifecycle stuff that was the most intimidating so if I missed that page it might explain a lot
@shaun-mahood: I haven’t looked at re-frame, looks like app organization stuff which is out of scope.
@dnolen: Yeah it's definitely app organization stuff. From what I can tell it's sort of at the same level that Flux works (but my understanding of Flux is only from reading and watching about it so could be very wrong).
@shaun-mahood: yes don’t want to get in the way of stuff like this. I’ve heard people happily adopt re-frame approach with Om.
Fwiw wrt Om docs, @ericnormand has a course coming out soon on it :)
Reframe is a really nice way to get started with Reagent, especially when you don't know much.
Between all the awesome stuff happening in the cljs compiler, figwheel, cursive, garden and the react bindings it's an amazing time to be learning all this stuff. It feels like every week someone is taking away another one of my long term gripes with software development.
@dnolen: strange, but new 0.0-3308
compiles ~2 times longer than 0.0-3264
and likes to recompile deep dependencies. is it known?
razum2um: there’s an outstanding ticket to improve that, you can also disable that behavior (which is of course less correct) with :recompile-dependents false
@hlship to get going with re-frame ① look in the examples folder of the repo, particularly todomvc ② then perhaps use https://github.com/Day8/re-frame-template
@mikethompson: I'm starting to get going; dealing with re-frame, re-com, forms right now. A little awkward because of assymmetry: how you get data out (a subscribe and/or action) is not much like how you put it back in (a dispatch event)
@hlship: yep there is a "water cycle of data" flowing in a loop (think http://thumbnails-visually.netdna-ssl.com/water-cycle_521f29b8b6271_w1500.png) and that cycle has two distinct parts.
And the two parts of the data flow have different "nature". Just as the two flows of the water cycle have different nature, despite being about water.
@mikethompson: Have you done any experiments with adding namespaces to re-frame? I'm finding that a lot of my dispatch methods are named things like <section>-<page>-<action>, which is really reminding me of the way I've gotten around in things like css and other non-namespaced languages
Using namespaced keywords is fine
razum2um: if that’s something that works in Clojure should probably work in ClojureScript
@mikethompson: Well that solves it then, thanks.