This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-11-10
Channels
- # alda (28)
- # announcements (7)
- # beginners (79)
- # boot (62)
- # cider (11)
- # cljsjs (12)
- # cljsrn (8)
- # clojure (111)
- # clojure-art (2)
- # clojure-austin (5)
- # clojure-conj (3)
- # clojure-dev (54)
- # clojure-japan (12)
- # clojure-russia (30)
- # clojurescript (354)
- # clojurex (5)
- # cursive (9)
- # data-science (58)
- # datomic (19)
- # editors-rus (3)
- # emacs (7)
- # events (2)
- # hoplon (5)
- # ldnclj (6)
- # lein-figwheel (14)
- # luminus (1)
- # off-topic (10)
- # om (191)
- # onyx (59)
- # re-frame (30)
- # reagent (74)
- # robots (1)
- # yada (19)
@dnolen: It's not pretty but here's a (probably buggy) hack I came up with for the transact!
reads thing we discussed earlier: https://gist.github.com/Jannis/66ebbcd791ad9b6e24a4 - just in general, was this the kind of "automation" (assuming it was built into transact!
) you were thinking of or is this a really bad idea?
I can already see a problem with it - parameter substitution. Although that could be solved using bind-query
. Whatever, take your time with it all, I just couldn't wait trying something.
Actually, parameter substition seems to happen at a later stage, so it's already working with that hack. Sweet!
Definitely a fine line that needs to walked here between convenience and something that’s straightforward to reason about.
didMount
only works once it renders initially. willReceiveProps
happens before the render
@mike it depends. you probably mean old om. New om is something completely different and has close to nothing in common with reagent. It's more a hybrid of react + falcor + graphql
I recommend watching dnolens talk from euroclojure (https://www.youtube.com/watch?v=ByNs9TG30E8) and reading through https://github.com/omcljs/om/wiki/Quick-Start-%28om.next%29 if you're interested
it is not literally graphql, just the idea behind it. It changes the way your components query your (local or remote) app state
next
is still apha but I believe a beta is coming soon (correct me if I'm wrong @dnolen). I recommend reading through the resources and decide based on that if you need this approach. If you think that's a overkill for what you are trying to do, use reagent
thought by escaping javascript jungle and refuging to clojurescript I don't have to make difficult decisions anymore. turned out I'm wrong. there is om, om next, reagent + re-frame,.. and the whole javascript jungle growing here too
@mike gdom is the google closure dom (https://closure-library.googlecode.com/git-history/docs/namespace_goog_dom.html). om.dom is, I believe, a wrapper for Reacts DOM https://github.com/omcljs/om/blob/master/src/main/om/dom.cljs
little self advertisement but my minimalistic markdown editor in om next just managed to become the highest trending clojure project for this week 😛 https://github.com/trending?l=clojure&since=weekly
@mike directly, it’s pretty unusual to see a ClojureScript library that doesn’t use some functionality from GCL
@mike assessing things on whether something does or doesn’t look “complicated” is rarely a good idea.
Either you see that it reduces complexity for the kinds of systems that you have built in the past or you cannot. If you cannot it’s really not a big deal … people are effective with all kinds of software systems.
I’m seeing a problem in advanced compilation with om next (using 1.0.0-alpha19, cljs -170):
#error {:message "No queries exist for component path (#object[RA \"function RA() {React.Component.apply(this,arguments);this.state=null!=this.ra?this.ra():{};return this;}\"])", :data {:type :om.next/no-queries}}
this is a good talk to review in the context of Om Next https://www.youtube.com/watch?v=ROor6_NGIWU
So we are having some confusion about putting a list component inside another component
Right now we are just adding a read method and recurses to the target key but seems brittle
1) every component that wants to query must have it’s OWN query and it MUST be a vector
Right, mostly just wondering if the implemention idea (invent an intermediary key) is the correct approach
if you work out what has to happen if you don’t enforce these rules you see there are many more problems
it wasn’t that we wanted to buck the rules. I think there are just ‘react components’ that have no need for queries.
With regard to remotes and parsing: I'm working on a nested set of components where remotes are involved. As I walk the query in read, I'd like to call the parser recursively. This works fine with locals, since I can return {:value (parser ...)}
; however, the return value of the parser
on a target is a query, so I cannot exactly return { :remote (parser ... :remote) }
because that is supposed to be an AST.
I can use expr->ast
, but then I end up with a vector of vectors (because the outer parser wants to wrap the elements of the parsed selector in a vector to make it a query). I can dance around the data structures and make it work, but all this seems kinda messy, and I'm wondering if the story is still evolving, and I should just not be trying this particular thing yet. Or perhaps I've missed a simple trick.
@tony.kay: ok so the problem here is that ast parsing doesn’t compose simply like parse does
i’ve also ran into this @tony.kay. i ended up using gather-sends
. which i’m not sure is public
(let [ast (exp->ast selector)] {:remote (update-in ast [:sel] #(parse env % :remote))})
that might work...I see the general idea. Yeah, I was trying to post-convert the returned query instead of that.
right I think this should work and it supports recursion pretty much as well as the value oriented stuff
@tony.kay: no problem, happy to know if how it works isn’t satisfactory for some reason
I'm not sure how you'd do an app of any size without recursive parse...if you have any nesting where the top-level components are all local, and then you have nested components that need to hit a server, well, you have to compose the remote stuff to root...how would you do it without recursion (well, other than walking the sub-query manually...but isn't that a recursive parse you've just written manually???)
I am, and you do, but there are still a couple of level to go through, and recursion seems the natural choice to get to the part that is "ready to send"
but yeah, I don't have any suggestions for making it simpler...I just wasn't seeing the algorithm, and was making sure you didn't have further dev you were going to do in this area that would make is easier somehow.
I think it wasn't very evident to me (and evidently others like @jdubie) because I was thinking of the AST as an opaque thing...an implementation detail to be passed around, but not messed with, so I was trying to convert it after the fact using a known function
and I’m also not yet convinced that helper functions don’t help with the cases where you have to get through the first couple of levels
so I could very well be wrong about this and people should show simple examples based on real world things that reveal things require lots of effort
I ran into the need for recursive queries immediately. Basically anytime a component wants to render a subcomponent that wants to query for root keys (doesn’t know its a sub-component).
so far, I'm seeing a recursive use of simple read/parser calls as the simplest way to walk down a nested query that contains a mix of local/remote stuff...but things like specter also seem like possible contenders...nothing prevents me from transforming the nested query at the "top"
but I’ve since been trying to think of the queries more as requesting what data you need and using extra parse functions to do the plumbing and not care as much what the real underlying data structure looks like in my components
I still lean towards recursion, because most people get recursive parsers pretty readily.
recursive parse should work, but it may very well be that other methods are better suited for different kinds of apps
@noonian the root values problem is a different thing from queries. This is why I fixed up shared.
if you need to push user info, internationalization etc. around don’t do that with queries
For instance, if I have value :msg in my state that shows notifications to the user from different parts of the app, so many components want access to it to render it.
not a great example since it would probably be the top-level components responsibility to render the msg but thats the type of thing I’ve ran into
I’m having a hard time imagining replicating global dynamic information into each component
My usecase for recursive queries was that I was trying to make a “layout” component that renders a different sub-component based on the app state (using query mutations to change its query dynamically). This is a much more complex example but in this case I desired that all of the sub-components be unaware that they were sub-components and that the “layout” component not require special knowledge about the subcomponents. So a different motivation for wanting recursion but I think the implementation issue is the same as with the :msg
example.
I’ve kind of tabled that experiment for now though and am just using a giant union of the queries at the top level. I saw some discussion in here about maybe adding delayed queries or something in the future and I think that is trying to solve the same problem as I was.
anyway I’m just mentioning this because it sounded like you wanted to hear more use cases
@noonian that’s an interesting sounding example but hard for me to understand the issues without knowing more details about you actually tried and how you went about it
at this stage it still difficult to know if people are getting stuck on how to reformulate the problem - or a limitation of what’s there
I also found myself using params in place of state for the component since I had to mutate the query at the same time as change the state but also have access to the (initial) state in my static query
impl.
Is it allowed in om.next for a component to return multiple idents?
I think it probably doesn’t make sense, but I have been thinking about how to have multiple pieces of normalized data
@chris-andrews: not allowed
Ok, follow-up, is it a bad idea to use two subcomponents that each have an ident, and then have their parent component utilize their data? I think I can actually work around this, but some things like WebGL can be a little tricky to break down into components, but the ident is really useful for data normalization
So essentially, each child component’s query gets used, but they just return nil in their render function, and the parent component actually uses their data because it has access to the WebGL context
@chris-andrews: this also doesn’t make sense to me
Simply because their query enables data normalization via Ident
. The whole scene needs certain data, but a parent component can’t have multiple Ident
s, so that seemed like an option to me for working around that
I think it’s probably not a well thought out question, and it’s not a big deal. Mainly was just wondering if the mapping definitely needed to be 1 component = 1 Ident
Ok, thanks for clearing that up a little. The only reason WebGL is involved is because in the past it has been a little tricky for me to render children to a scene, because you need the parent context, but that’s really not very difficult to work around
pretty excited about it, you should be able to build up graphs of objects that don’t have remote permanence yet (and their corresponding UI elements) and batch a transaction
if there are tempids in the remote transaction result then the temporary ids and UI bits will automatically be migrated to the new information
removes a giant complexity hairball from the kinds of things you see people do in more sophisticated client apps
the only thing left to do is cache eviction and I have a pretty good idea how to keep it dead simple for most applications (nothing for users to do)
if there’s anything people would like to see changed, enhanced or tweaked now is a good time to speak up.
Also simple complete examples of conceptual difficulties as we’ve already discussed today are welcome - they will help determine if there are any real remaining gaps