This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-12-09
Channels
- # beginners (140)
- # boot (163)
- # cider (43)
- # cljs-dev (50)
- # cljsjs (5)
- # cljsrn (38)
- # clojure (152)
- # clojure-austria (10)
- # clojure-berlin (9)
- # clojure-dev (11)
- # clojure-japan (1)
- # clojure-miami (2)
- # clojure-russia (147)
- # clojure-sg (12)
- # clojurescript (244)
- # code-reviews (3)
- # cursive (104)
- # data-science (5)
- # datavis (15)
- # datomic (35)
- # editors (4)
- # hoplon (1)
- # ldnclj (11)
- # lein-figwheel (14)
- # leiningen (22)
- # off-topic (53)
- # om (373)
- # omnext (2)
- # onyx (67)
- # parinfer (193)
- # re-frame (23)
- # reagent (89)
- # yada (7)
Is there a way to obtain the query of the root component instance from the reconciler?
I see there's om.next/app-root
but that returns the component (e.g. Root
), not its instance, correct? So if you use (set-query! this ...)
to change the query of the instance, is there a way to get that from the reconciler somehow?
@noonian: Yep, that's what om.next/app-root
does. I was wrong, it does the right thing, it returns the instance. I just had a local variable shadowing the result...
I simplified my version of the router-example (https://github.com/thos37/om-next-router-example/blob/simplify-datascript/src/om_router/core.cljs) to have the Root
component just have a simple [:route]
query: (om/get-query Root) -> [:route]
. When it's parsed, it returns a map with the route as a key pointing to the data needed by the child Page component for that route: (parser {:state conn} '[:route])
-> {:route {:index {:pg/title "Welcome to Take 2", :pg/subtitle "Take 2 minutes to change your self. You're the only one who will."}}}
Does this seem reasonable?
Any hints on how to have (or even think about) streaming data from websockets drive multiple graphing widgets on a page in an om.next based app?
when you get a message on the websocket, call merge!
with the reconciler and new data to get it into the state
Is the main problem with having an opaque query like [:route]
that it requires multiple round trips to the remote store on each page transition, whereas something like [{:pages {:index (om/get-query HomePage) :login (om/get-query LoginPage)}} :current-page]
enables the server to send back more data up front?
The server-side parser does not include {:foo <val>}
from the result if the read for :foo
returns {:value nil}
. Is that deliberate?
@tony.kay: no rush, but I resolved OM-528, so if you want to look at OM-526 do so at your leisure
good example of how much a small amount of terrible code can have serious repercussions
@dnolen: ok, will do. jannis supplied a reproducible case for the problem in db->tree as well. Something about the recursion limiting isn't quite right.
@tony.kay: so I actually resolved OM-526 with OM-528, what actually needs to be fixed are your own merge-union-join tests
@tony.kay: I'm off to sleep but keep me posted on the progress or if you need any help (doubt it ;)). Thanks for looking into it
In react 0.15, I really like the stateless function components, and the simplicity of it (props -> vdom). In cljs, I’d like something like (defsimple name [props] (dom/div nil (:title props)))
. Is this a thing that’s supported in om? I could do it with a macro, but don’t want to reinvent the wheel.
@jaredly: (defui Name Object (render [this] (dom/div nil (:title (om/props this)))))
+ (def name (om/factory Name))
not good enough? 😉
yeah you can do it with just functions with the caveat that it has to be a child of a stateful component
inside yr defui / reified component thing you can build out helpers that take data and return vdom
hey guys, i ran into an issue with react native and om next and datascript involving how rerenders from the root were handled. i made a gist of a reproduction case, as well as the reconciler implementation that seems to address the issue. https://gist.github.com/jobez/9ea1963b2b07454a28a6
how can I disable React warnings ?
"Warning: render(): Rendering components directly into document.body is discouraged, since its children are often manipulated by third-party scripts and browser extensions. This may lead to subtle reconciliation issues. Try rendering into a container element created for your app." - ok, ok
I'm having trouble with queries in nested components:
Uncaught #error {:message "No queries exist for component path
(example-app.views/Root example-app.views/Users example-app.views/User)", :data {:type :om.next/no-queries}}
The query metadata seems to be intact: https://gist.github.com/nblumoe/d2ca51d93403f52b2080
Obviously :class-path->query
is missing the corresponding value, as the error message indicates and the gist code shows. Why might that be?
hi nblumoe
how are your components queries structured
hi @johannjohann I could narrow down the issue a bit more. let me get a gist ready with the components/queries
are you trying to set a query
@johannjohann: updated the gist with example components. I would prefer to define a query on Users
however, this results in the error described above.
Keeping Users
without a query, but defining the query on the Root
instead does not result in that error, because then the component class-path is Root > Account
instead of Root > Accounts > Account
if you click that little info icon in the upper right hand corner it has some pinned chats
im dubiously trying to figure out how to link one particular dnolen statement lol
will just c&p
dnolen Nov 10th 1) every component that wants to query must have it’s OWN query and it MUST be a vector
@nblumoe: If you want to include Users query in the Root component you should do this with a join, e.g. [:app/version :routing/current-route {:users (om/get-query Users)}]
, and Users query must be a vector as @johannjohann pointed out. Basically, you can't steal queries from another component. You can find some discussions about it from yesterday if you search for "steal queries" in this slack channel.
is there like a tool that allows slack communities to reference convos in wikis and stuff
@johannjohann: not sure about that, but you do have this slack's logs here: http://clojurians-log.mantike.pro/om/
@jaredly: what’s needed to support stateless function components? it’s just a function right?
"If you want to include Users query in the Root component" this seems to indicate, that this would be optional. From my understanding it's mandatory though. Doesn't the Root need to "collect" all queries of subcomponents?
Not using a hash-map, but a vector for Users
was, what I did first (according to the cited statement and the docs of HAVING to use a vector). However, I could not successfully merge that into the Root
query then. Either ended up with an invalid query syntax, OR lost the meta data needed to identify the component that defines the query.
as already state the query must be a vector but that’s not the actual conceptual problem
ok, good to know, so https://github.com/awkay/om/wiki/Om-Next-Overview#reads-and-the-query-grammar really is outdated by now (last query being a map)
Oh, yes. Not talking about changing anything. Rather trying to understand how to use it properly and what the intended design is.
this said routing is a concern but it is a global one and one that we intend to support in a global way not at the level of individual component. this story is getting sorted out.
Fair enough. Thinking in terms of React it also makes perfect sense to pass the data from the parent to the children.
I’m having some trouble with normalization, I have a chain of 3 components and for some reason the reconciler can’t normalize the data.
@txus: you basically have one component too much
your root should be MapView
then everything works
because there's no :map-props
in your data
I know, but isn’t this what we discussed yesterday, that you could make up artificial nestings to create a path between components?
you can
but that's unrelated to normalization
I was pretty sure I had something similar working yesterday though — a RootView that makes up an artificial nesting to pass data to subviews, and normalization I think it worked? maybe not
so in the normalization case, you'd have to wrap your state in a :map-props
then everything works again
and you can use the RootView component
what if I modified the query instead of changing the state? then I’d have the problem of RootView stealing MapView’s query no?
notice that it's a really simple rule: component's queries have to match the data's shape
what I don't understand is why you have one component too much, as I've said before
the idea is that RootView will have other subcomponents, not only MapView, that will have their own subqueries
your MapView component already has all the information in the state ( at least for this exampe)
then you'd want a union
or maybe not
I’m confused. Yesterday you posted this: https://clojurians.slack.com/files/anmonteiro/F0G5C0RC4/Untitled.clj
from my point of view I’m doing nothing different from that, but for some reason normalization doesn’t work in this case :S
I got your example to work with a hacky thing that I'm not sure it's supposed to be used
which is basically using that approach
of my snippet
but you'd have to pass the state to the reconciler like this: (om/tree->db MapView init-data true)
so basically is just working around the problem that you have, it's not really solving it
because your data only matches your queries up to MapView
okay, so what I should take away is that component queries must always match the shape of the data, no matter what
@txus: https://gist.github.com/tomconnors/c1cceaae84fd059e37a3 this was posted maybe 2 days ago
it handles exactly the case where you can't have "auto-normalization", to steal David's words
in fact you can write a query you never use for anything except the normalization of local state
then I can not use auto-normalization with the RootView query but rather normalize it myself and pass it as an atom to the reconciler
ah this morning I still wasn’t completely sure if normalization had to do with the parser reading the data lol. The concepts are slowly getting clearer in my head, even though I’ve been using om.next for quite a while now heh
@dnolen: why did factory
become a top-level thing with om.next when all the details were hidden away with om.now?
@txus: note that this is what I've done with your example; normalized it and passed it into the state
and in the end factory
is useful - you can do validation, :keyfn
all these other things there
@dnolen that makes sense. it struck me as something “new” to learn for om.next that didn’t seem crucial to the problems next is solving
@dnolen: Getting my head around factory
: Is there ever a reasonable case for having multiple factory
s for a single defui
component? Would you ever use different :keyfn
s or :validator
s for different cases?
one thing that nobody has pointed out is that it with :keyfn
it just kills off all of this build-all
junk
since writing a factory is kind of a once thing, and the other stuff you have to deal with constantly as you change your app
I'm trying to get my head around whether factory
being a separate form in the file is functionally useful or just syntactically easier
I'm not trying to change it. I'm trying to lean on it to glean some understanding of the thinking behind it.
i’m just spending hammock time on next, so making sure i spend time on stuff that isn’t rock solid in my mind
right it’s just place to do constructor customization that I don’t want to put into defui
it did make me revisit some React stuff that i didn’t need to really think about before. i’m cool with that, because i got burned too many times by magic i didnt understand
but, i did want to understand and be able to articulate the benefits of simplifying the factory code
there were many brittle hacks in the previous Om in the attempt to avoid this that are now gone
@nblumoe: Let me know if there is a specific thing that is out of date in that overview. I'll fix it. Working on a tutorial that will probably supersede that, but I don't want it saying things that are wrong or misleading.
For reading joins on collections can I do (mapv #(parser (assoc env :state (atom %)) query) col)
?
I fairly consistently get the following error on figwheel reloads, anyone get the same and possibly know the cause?
I'm assuming it is a load order or something like that, but haven't been able to track it down yet.
@dnolen: Design question. In send, the callback is essentially merge, which in turn uses the current root UI query. If I've fetched something that is not in the UI (yet), is there a recommended approach to getting that data into app state?
Perhaps I'm doing something illegal: Is it legal to put a query fragment into query params?
for various reasons you may want the process by which you create queries to be more flexible for some reason
😄 As I think about it, I can solve my immediate concern with unions. My real question is "is it OK to grab app state during send and swap against it?"
ok. I can definitely see ways to plug into merge-tree et al. Just didn't know if watches on that atom would cause problems somehow
for swap!
the main problem is avoiding re-renders from the root if you don’t want that
ok. That answers it. Mostly I'm asking so when I'm working on docs I don't mis-state something.
Did I share http://github.com/jannis/om-mantras / http://jannis.github.io/om-mantras/ yet? Only two components so far but I'm happy to add more if there are any good ideas.
The idea behind creating this was that there are cool widgets out there (like selectize
) but they all come with heavy styling that's a pain to override. And they don't use Om. 😉
Yeah, looks good. Filed an issue for you with ideas on how to fix your known issue on selectable.
@dnolen: From a design standpoint, does it make sense to have something meant to generate query/ident objects that are not UI? I know we can use defui
for this, but in cases where I'm using defui
to generate artifacts for dealing with the fact that my server query/response does not match my UI (e.g. I just create them so I can leverage tree->db
), it seems like a lighter weight defquery
might make more sense.
no problem...easy enough to rename our uses of it later. I'm sure the shape will remain.
I can’t get Lein to do what I want, and I’m already a Cursive user, so I just created a pom.xml with all the dependencies I actually want
I'm not a cursive user (yet) but I might be if it had good support for boot, which I can get to do what I want, unlike lein - like you say
How do you run the tests from the REPL then? I tried (in-ns 'om.next.tests)
(run-tests)
but that doesn't work.
@dnolen: Fancy an alpha26 release? 35 commits since alpha25 and quite a few useful fixes
you need to get the src/test dir into your source paths for however you are running the tests
I don’t have them working personally though, but I think that is the problem you’re having
@jannis: how are you running the figwheel script?
@anmonteiro: I'm not a figwheel user so I may be doing it wrong: rlwrap lein run -m clojure.main script/figwheel.clj
so if you're using lein you need to add "src/test" to you lein :source-paths
vector
Done that: jannis@columba ~/o/om> grep test script/figwheel.clj :source-paths ["src/main" "src/devcards" "src/test"]
i mean
in project.clj
I thought about it but didn't write it, how silly
This is one of the reasons why I'm not using either of lein and figwheel - just don't know where to put what and then you have :source-paths
in different places...
@anmonteiro: Perfect, that worked
cool!
@jannis: btw you should try the node repl instead of figwheel's
faster startup time
so rlwrap lein trampoline run -m clojure.main ./script/repl.clj
Ok, tests are running, my new test for #531 fails (as it should) and a quick "fix" breaks other tests. Nice
Since Om Next UI components are just legit React components, using a JS React component (like this one https://github.com/zippyui/react-date-picker) should be straightforward right?
I think the hard part will be getting it included in your build (and surviving advanced optimizations). It looks like that component uses commonjs or w/e for modules and may not be on cljsjs
Great! We love Clojure and use it heavily for our backend services. So I was hoping to start using CLJS really soon.
Just wanted to be sure I could speed up dev using third party components, you know how product people are just thinking about features ASAP.
@noonian: @jplaza the standard thing to do is to just build all your JS stuff with React Tools or whatever
annoying, but it’s not something you have to do much and there’s pretty good documentation out there and examples thanks to CLJSJS
eventually we’ll get a good CommonJS story but that requires more support from Closure
Yeah, its definitely doable. It just isn’t as easy as using a cljs lib or js lib that has already been packaged for cljsjs.
@dnolen: last thing I read, Maria Geller was working on making this less painful, or was it something else related to JS dependencies?
OK, thanks. I will start playing with Om Next and hope to have something in production in a couple of weeks
@jplaza: haha, things are coming along but we’ve probably got a solid month or so before Beta
Can someone explain to me what Object
means in a defui
? It appears to be the protocol that defines render
, but clearly that's not right…
Object
means all functions below it are regular JS object methods, which render
is as well - it's the regular render
method from React, I believe.
(defrecord Foo [bar baz] Object (hello [this] ...))
should be possible as well I guess?
@tony.kay: I see the bug is fixed, but queries in the union do not seem to cause process-roots
to promote the queries to the root.
Ah, I see. So, you're not trying to just walk past the union to the target subquery, but instead include one of the specific items of the union as the root query?
well, I don’t think either works right now. I do want specific items of the union as the query, but I also tried manually annotating the union’s query with the meta data {:query-root true}
and that didn’t seem to do anything either.
Hm. So, I'm not using unions with process roots yet, and it is likely that more thought needs to go into it. When you do a local parse phase, you make a real choice (X is what I see in the app right now). When doing the remote parse phase you can also look at the app state and resolve "which path" is of interest right now. I was assuming that you would walk down a bit from there, and bottom out at server data, then mark that bit as a root.
it is possible that neither of those works. The only test is that if we see a union, we preserve it. Basically, the updated code tries to resolve the issues that are obvious (more than one subquery might promote to root). As I think through it, I did not address any union case other than preserving it. If you want, let's think through it.
In my case, my union is just to support routing. So in my read function for the :join-key
, I call the parser recursively in remote mode to get the remote query of the current page.
What I’d like to be able to do, is just add :query-root true
to my default read function, and not have to do any custom logic anywhere else so process-roots
just works
it would be each element of subqueryA
that has a query annotated with {:query-root true}
metadata
next most convenient that I’d also be happy with is in my read for :join-key
manually adding the metadata to the remote query subqueryA
I think you’d want to check each branch and compose all the root queries into the result root query