This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-07-21
Channels
- # admin-announcements (24)
- # beginners (80)
- # cider (18)
- # cljs-dev (12)
- # clojure (94)
- # clojure-berlin (15)
- # clojure-dev (10)
- # clojure-gamedev (3)
- # clojure-italy (38)
- # clojure-japan (4)
- # clojure-russia (109)
- # clojure-sg (1)
- # clojurescript (161)
- # code-reviews (29)
- # core-async (17)
- # datomic (20)
- # editors (14)
- # instaparse (17)
- # ldnclj (9)
- # off-topic (9)
- # om (2)
- # onyx (2)
- # re-frame (11)
- # reagent (46)
@wei Did you check out the Reagent channel?
@ivanreese: I didn’t know there was one, thanks
@wei: No sweat!
how do I test whether empty? will operate on something? I thought it was coll? but (empty? “”) => true (coll? “”) => false
wei: https://github.com/clojure/clojurescript/blob/r3308/src/main/cljs/cljs/core.cljs#L935
Yeah, it looks like empty?
does a little more than its docstring implies.
I’m trying to avoid (empty? 777) => Exception, 777 not seq-able. That’s why I’m looking for this test
@dnolen: is there a function where (f “") => true and (f 777) => false. (satisfies? IEmptyableCollection “”) => false
I’m getting false
returned from (instance? js/String "hi”)
. I’m pretty confused by this, is it expected?
This happens in a figwheel REPL, http://clojurescript.net, and from within the runtime of my project
There’s http://dev.clojure.org/jira/browse/CLJS-98 but that was resolved years ago
@danielcompton: why are you doing that instead of string?
. JS primitives will return unexpected instanceof
checks.
@dnolen: I was converting some code from Clojure to Cljc, and it was using instance?. I forgot all about string?
Is it expected that these tests fail now: https://github.com/clojure/clojurescript/compare/11e8bfe75d...53e5d19370#diff-3001f7cda7aa7395b7df737863fd8d3cR733
@danielcompton: just use string?
@danielcompton: those tests may or may not fail, they aren’t failing for me, but that’s really besides the point.
cool, string?
it is
thanks!
At the risk of being redundant… has anyone been able to get Om to work within Electron?
My app compiles but at runtime it is telling me that ‘React’ is not defined… and yet I can see the (minified) react code in the generated main.js
I’m guessing there may have been a symbol rename that is making it unresolvable.
I tried using :optimizations :none but that didn’t help… so maybe not.
@kahunamoore: have you checked that it's in the correct order?
does putting a script tag after the html tags ensure that the dom is ready when the script is executed? (not cljs specific)
so it’s important that it resides inside <body>? that’s puzzling, since body can be omitted. but it might be some legacy thing, regarding IE or something, I don’t know?
Oh… the good old days of HTML 3… and the promise of XHTML and XHTML 2.0! Good? who am I kidding… it sucked.
Anyways, I’ve always been using something along the lines of jquery’s document.ready, or the DOMContentLoaded event, but I guess that’s not necessary
I am converting my Luminus generated web app from secretary to silk, and as I follow ks-front-routing-example I notice it uses an atom to store the current route (https://github.com/metosin/ks-front-routing-example/blob/master/src/clj/ks_front_routing/ui/routing.cljs#L10) while Luminus uses the session (https://github.com/luminus-framework/luminus-template/blob/master/src/leiningen/new/luminus/cljs/src/cljs/core.cljs#L53). What are the implications of one vs the other?
@pupeno: I was writing up an answer about how in-memory atoms differ from sessionStorage and why for routing it is probably preferable to use an atom when I decided to look at the source for reagent.session
. Turns out it's just named poorly and uses an atom as well! https://github.com/reagent-project/reagent-utils/blob/master/src/reagent/session.cljs
@domkm: yeah… I actually ended up finding that same information. Based on the description of reagent-utils, it seems to be designed so that you can run code intended to work with lib-noir on the client. Maybe @yogthos can shed some light here.
Any ideas what’s going on here: https://github.com/luminus-framework/luminus-template/blob/master/src/leiningen/new/luminus/cljs/src/cljs/core.cljs#L42 why are the functions being interpreted as vars? is this something ClojureScript releated?
@pupeno I was wondering the same thing. also here:
(defn mount-components []
(reagent/render-component [#'navbar] (.getElementById js/document "navbar"))
(reagent/render-component [#'page] (.getElementById js/document "app")))
@curtosis: I think the reason is to have a fresh copy of navbar and page when they get reloaded… but that doesn’t make sense in my brain anymore… it did some time ago.
interesting. I assume by default that there must be a reason for it, so am curious as well.
@pupeno: reagent-utils aren't related to lib-noir, just the session API is taken from it that's all
@yogthos: I just tried it without it and it auto reloading works fine… not sure if that’s due to other changes I made to the file.
what happens is that the old symbol will be referenced, and when the file is reloaded then a new symbol with the same name will be provided
I wonder if this example, which doesn’t use var, then, suffers from reloading issues: https://github.com/metosin/ks-front-routing-example/blob/master/src/clj/ks_front_routing/ui/routing.cljs
I'm browsing through the routing discussion from yesterday and today — I tried using React (Reagent and later Rum) with silk and bidi and it just didn't fit for me. The problem was that I noticed that I ended up introducing yet another translation layer (URLs to symbols to component configuration).
What worked well for me was a solution that couples the component hierarchy to URL hierarchy. That might not work for everyone, but for new apps it's very nice. You get the benefits of composability: the same component with internal nav structure can exist in multiple places in your app and its nav structure will work without changes to the global "routing table".
@jrychter: I’m experiencing some of those issues too… the truth is that routing has three components if the route is to be bidirectional: the path, the identifier and the code to run.
I don't like the whole idea of "routing". I think it's something we brought in without much consideration, mostly from the Ruby on Rails world.
@jrychter: I don’t think connecting to the code through the identifier of the route is that bad, it’s just such a central component of the app and deciding on how to do it when you are new to the language, the library, the framework, etc is hard, as at least me, I don’t know the implications of my decisions.
URIs were designed to be hierarchical. We now have hierarchical componentized apps. Why stick to the idea of "routing"?
I’ve created a new channel #C07UQ678E for discussing development on ClojureScript itself so to avoid flooding this channel with information that may only be of passing interest to application developers
@pupeno: It becomes really bad once you try using a single component it two different parts of your app. What do you do? Duplicate the route entries and create another set of keywords?
jrychter: what you build sounds similar to EmberJS, did you have any experience with it?
@pupeno: No. The ideas come from weblocks, a common lisp framework I used to contribute to.
jrychter: well, I have no idea, I’m new to building components for UI in the browser, which is why I don’t like having to make this architectural decisions, I don’t have enough information about it yet.
You can see what I'm talking about here: https://partsbox.io/demo/part/1c265b6d-18f8-11e5-957e-9bcf9dabe7b7/ and here: https://partsbox.io/demo/parts/1c265b6d-18f8-11e5-957e-9bcf9dabe7b7 — this is the same component in two different places, with local navigation.
The component has no idea where it sits in the hierarchy and there is no global "routing table". I would end up tearing my hair out if I had to specify all the nav entries for this menu multiple times.
By "component" I mean the electronic part display with the local menu on the left. That's the local nav.
@pupeno: sorry. Click on https://partsbox.io/instant-demo first, this will log you in.
What I do is use pushy to get history events, then split the URL into "tokens". These are passed down the component tree as props/args (nav-state), containing consumed tokens and remaining tokens. Any component is free to "consume" a token, by passing it from remaining to consumed. It then passes the new nav-state down to its children.
The only drawback is that you do have to pass another parameter down your component tree. But it isn't that bad. And it means that local navigation is encapsulated within the component and is composable.
@pupeno: Yes, through pushy https://github.com/kibu-australia/pushy
In a larger app there is still a "global" part, but it's not a routing table, but code that can generate global links. You will need those for certain parts of your app. In my case, that's 6 one-line functions.
I don't use a framework. I do use compojure for server-side routes and hate it, I plan to remove it eventually. The app uses Sente, Ring, and RethinkDB for data storage.
@jrychter: RethinkDB + Sente sounds like you have data that changes on the server and want the client to automatically update. Is that true?
you should have a look at bidi for routing. Pretty desing, composable, routes are data etc.
@pupeno: Yes, that's the plan. But even if you don't, sente is great for writing apps.
@ordnungswidrig: I did, it isn't much different from silk. It's the same concept, a "routing table".
Linking components directly to routes in a hierarchy leads to a lot of complication, speaking from personal experience with React + ReactRouter (which I think is very similar to Ember)
@profil: Oh, it's just that my brain has problems dealing with routes being ring handlers. Functions returning functions, generated by macros — I always end up with a mess that barely works and is very hard to debug. I'm sure it's fine for people who can conceptualize all this in their heads. I can't.
@domkm: I think this depends on the application. I can see how it could be a huge problem if you have externally-mandated URL structure that you have to adhere to.
@jrychter: Even basic things like authentication (which should be easy to handle with a parent auth component) becomes very complicated in ReactRouter. All of the examples work when used individually but it's absolute hell when you have to combine them.
@domkm: Well, I don't know ReactRouter, so I can't speak for that. What I do know is that I encountered no problems writing PartsBox, which isn't such a small app (and it does have authentication). I am very happy with the results so far.
One thing: I'm not sure what "Linking components directly to routes in a hierarchy" means. I don't link them that directly. A component doesn't have to consume any tokens — it just needs to pass the nav-state map down the tree to its children. So not every component in the tree is reflected in the URI structure.
@jrychter: Oh, yeah passing routes down the tree is my preferred way as well. It's far superior (less complicated) than ReactRouter and Ember routing in my experience.
@pupeno: http://jan.rychter.com/enblog/ — but I have to write it first. Which might take several days.
if you live in Austin, TX https://twitter.com/swannodette/status/623527687932481536
@bbloom: I’ve continued studying you vdom implementation (it’s a great read, highly recommended!). I was wondering about child diffing. The implementation ( https://github.com/brandonbloom/cljs-vdom/blob/master/src/bbloom/vdom/patch.cljc#L58-L76 ) seems to imply that if you remove the first item all the rest are rerendered. Is this correct? I think that React uses a more efficient algorithm?
@jonas: if i understand your question, correctly: No, changing one child will not cause the rest to need updating. The overall approach treats property sets separately from parenting
@jonas the code you highlighted essentially works by re-arranging all the nodes via a virtual DOM .insertBefore method. Then virtual .removeChild for the remainders. This models that when a node is moved to one place, it’s removed from the previous place.
@jonas My experiments showed that insertBefore tends to perform surprisingly well, suggesting that browsers use decent data structures for node children and/or it doesn’t matter for small numbers of children. For larger numbers of children, my code should behave well b/c it uses rrb vectors for cheap splicing. Slow part in rendering may be the search for a node, not the insertion of a node, but i figure that for a few thousand children tops it should perform just fine & in that case you should use a virtualized scroll panel or canvas or whatever other non-dom thing, since humans can’t really look at / click on more than a few thousand boxes on a screen
but insertion sort performs pretty well if the data is mostly sorted and stable over time, which UI elements are… up until you do something like totally change the sort order by like clicking on a column header or something in a table view. but you do that ONCE not like 60 frames per second
anyway, hope that clears it up. lmk if you have more questions or if you discover my assumptions don’t hold
@denik: Planck is really just a small PoC right now, but it sounds like there is interest in seeing it grow into such a thing.
Quick question: I transferred a jar
from my Mac to an Ubuntu. On one page, I used if
to display one div or another, based on a boolean (it's a Reagent SPA). This doesn't work on the Ubuntu, with the same jar, and Java 8 installed. Everything else works though. My google-fu reveals nothing helpful. Is there some Ubuntu-ClojureScript gotcha I should be aware of?
I'm having a look at RethinkDB and the clj-rethinkdb client. Has anyone used this from ClojureScript for real-time updates, perhaps through sente?
@petrus I’m working on this as we speak
How do I send you cupcakes?
Just pushed cljs support to master yesterday
for generating queries
@coyotespike: which Java 8 on Ubuntu? IIRC there are differences between OpenJDK and OrclJDK.
:thumbsup: glossing over commits now. If I wanted to "subscribe" to a table and get a callback when data changes, is that possible? Others say to use the JavaScript driver.
rephrasing: are they both using the same Java 8. at least a starting point for diagnosing.
@petrus RethinkDB doesn’t support direct connections to the browser so you need something on the server running the queries and proxying them back to the user
ah, I misunderstood. Thought there was a direct connection ala firebase.
You need something like https://github.com/mikemintz/rethinkdb-websocket-server
@curtosis: They are both using SE, Oracle.
or the rethink proxy that I’m building at the moment
Are there any reference impl. around? Ah, sweet. How do you feel about progress so far? Is there something I can test drive for you?
Yeah, good starting point
I'll keep poking around, I understand the JVM runs a bit differently in each environment. Might have to start developing via ssh...
Mikemintz work is probably closest thing to a reference impl
The stuff I’m working on is beta quality, and not well suited for the public internet as the query whitelisting is still quite basic
It works for our authentication and threat model, but not for a general consumer facing website
I’m not sure what I’m able to share, or how valuable it would be to an outsider, I’ll have a think
@coyotespike: if you are using source maps, I would try to debug in the browser and compare the differences between both deployments.
@roberto: looks like I'm using source maps in dev, but not in production. I'll monkey with enabling source-maps and using them to debug.
@lazy-lambda: Another place we can link in Replicator, once available: https://github.com/clojure/clojurescript/wiki#learning-tools
BTW does creating a shared cljs runtime for Android will be any good, for apps that want to execute cljs.
So that not every app has to bundle their own versions of cljs
@mfikes: Since there's so many fun rules for the app store, what kind of things are possible for Replete as far as saving files/namespaces for later, or synchronization with dropbox and loading existing files into the repl? 2 things I would love to be able to do - save code for later so I can work through a whole textbook or problem over days/weeks, and pass files between my computer and iPad.
Oh that is super cool.
@shaun-mahood: You can already do “open in” from other apps, including Dropbox.
@bsvingen: Whoa. That didn't even cross my mind.
That would be an amazing way to explore things.