This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-06-07
Channels
- # admin-announcements (4)
- # beginners (63)
- # boot (67)
- # clara (29)
- # cljs-dev (38)
- # cljsjs (10)
- # clojars (7)
- # clojure (336)
- # clojure-belgium (3)
- # clojure-dev (22)
- # clojure-greece (30)
- # clojure-nl (1)
- # clojure-russia (9)
- # clojure-spain (3)
- # clojure-spec (169)
- # clojure-uk (12)
- # clojurescript (45)
- # clojurex (4)
- # core-matrix (3)
- # cursive (58)
- # datascript (3)
- # datomic (18)
- # events (38)
- # hoplon (228)
- # immutant (5)
- # lambdaisland (6)
- # leiningen (3)
- # luminus (8)
- # off-topic (11)
- # om (113)
- # om-next (2)
- # onyx (10)
- # parinfer (7)
- # planck (22)
- # re-frame (11)
- # reagent (25)
- # robots (7)
- # spacemacs (3)
- # specter (10)
- # yada (3)
I don’t get it. In read
method for a collection, it’s up to me to filter data based on query?
so if I have read :big-list-of-data
and key
is :big-list-of-data
and query is [:name :id:]
, I can’t just grab entire list and return it as {:value big-list}
? I have to filter it down according the query?
You are free to return {:value big-list}
, but if your data is normalized you will probably want to call om/db->tree
on it at least. You might not care if your parser actually filters out unrequested keys at the last level of a query. I think most of the examples don’t use select keys or anything at the last level and so pass more props than requested to the component. If you are trying to use params for filtering you will have to do the filtering yourself.
The idea is that om provides small utility functions like tree->db
and db->tree
and you call them yourself in the parser as you need.
@dobladez: following up on your question the other about transact!
and the logic not belonging, the way I find myself solving that problem is passing the parent component as a computed prop e.g. (om/computed props {:owner this})
and in the component in which the transaction belongs, I call (om/transact! owner '[(tx)])
probably cleaner than passing callbacks here and there
what I find hard to grasp is the fact that the very top-level component (root) had to have so much knowledge of the whole app
Looking at the kanban demo, I cannot imagine how I'd structure the app if I had to add more and more functionality, like, say, authentication, admin pages, user profile, searching, etc... would everything have to belong to the Root ?!
every query must compose to the root, so in some recursive definition it always needs to know everything
that said, the kanban app was done a while ago when Om was in the first alphas and might not reflect the idiomatic way of doing things now
so I’d take it with a grain of salt
Another approach I tried was to add a "fake" key which I joined to from the root (basically, the :xyz
I mentioned above)... I couldn't really get it to work, but I was close. I'll resume later today if time allows
so, the root's query would be something like [ {:root (om/get-query ItemList) } {:root (om/get-query FooList} ]
. Makes sense?
@anmonteiro: Now, one problem I see with the "everything at root" like the kanban demo is that pretty much many transact!
would result in a re-rendering from the root, even if only a single component needs it
@dobladez: not everything needs to belong to the root, but it must compose to the root in a recursive sense
that’s right
also your little snippet isn’t quite accurate
your have 2 keys with :root
hmm... right.... so, I guess adding a level on indirection here does not really solve my problem 🙂
another dumb thing I tried was including the child query directly at the root with no join 🙂, like: [ (om/get-query ItemList) ]
right, that just won’t work
stealing queries is not allowed
well.... I didn't get to structure thing the way I wished.... but at least I got validation that I was not all that stupid. I mean, I thought I was misunderstanding and that there's gotta be a way
What's the difference between computed props and normal props? Why (om/computed props {:extra "stuff"})
rather than simply (merge props {:extra "stuff"})
?
so we want to be add event handlers onto the value we flow down without messing up equality checks
@peeja yes that might be the case - I haven’t heard people complain about that one much yet
@dobladez I've used fake|synthetic root keys, which work, but eventually put real keys in the app-state with {}
vals so I could use a single db->tree
read. Child components are usually root level like '[{[:root/foo _] [*]}]
I suppose in my experience handler definitions tend to change at the same time the main props change, so that does sound right. Neat.
@dnolen: actually I think we use computed in equality checks? https://github.com/omcljs/om/blob/master/src/main/om/next.cljs#L1771-L1772
@anmonteiro: ha, I was only looking at shouldComponentUpdate
@dobladez: also - a big hurdle for me was understanding that you are constructing a tree of data for the UI with meta paths, trying to be clever with how you query data at the root level and pass it down is an easy way to break the idom
@peeja: I'm new to this, but my current guess was to leave props for those declared in the components' query, and any additional prop passed with om/computed
I mean, the semantics may still be WIP, and that's fair. I'm just wondering if I'm missing an important concept.
well... I see quite a bit of metadata being used on the queries... leaving it untouched sounded like a safe choice 🙂 Does merge
retain metadata?
@peeja: here’s the thread for computed
: https://clojurians-log.clojureverse.org/om/2015-10-28.html
so computed is way of saying here some stuff that needs to survive if the child changes it own state
@anmonteiro: Cheers, that'll help
@peeja: the key to understanding what David is saying is that when a component down the tree changes state it gets its props fed directly to it, they don’t go through the parent. So without computed things you had merged into props will be lost
Right, that makes sense. So it'll get the props from the reconciler, but the computed values from…the last time its parent gave it some?
that’s right
this is the code: https://github.com/omcljs/om/blob/master/src/main/om/next.cljs#L1771-L1772
see it saves the computed props there
So, computed values shouldn't depend on queried data, then (which I don't think is surprising)
right
If a parent passes a callback into a child, the callback shouldn't close over data the parent pulled out of the child's params (and the parent shouldn't be pulling data out of the child's params to begin with)
in practice you’ll want to pass event handlers and style stuff
re: closing over there’s a discussion about that in the thread I linked
And the reason this didn't matter until Om Next is that now we have a reconciler feeding the component new data directly
yeah I suppose that’s right
I don’t know how om.core did reconciliation but I think it relied on React
I might be wrong though!
For context, I'm attempting to write om.core
code in a style that will be as easy as possible to migrate to om.next
, so I'm thinking through the distinctions a good deal. 🙂
Right now I'm working on "simulating" set-query!
with set-state!
and API calls. It's not pretty, but it will be one day.
Is it only components with Idents that get params fed directly to them by the reconciler?
or does the reconciler have other ways of connecting components with data from the state?
can someone who’s most familiar with process-roots and :query-root
true, can explain this to me?
;; if I have in my root component join query like:
`[{:main-data ~(get-query Child)}]
;; and in the child:
[:child-data]
and then I do process-roots
trick in my send
method, so it would do the right thing by sending for child-data
, but putting it into the state as {:main-data {:child-data [...]}}
, how then now in the read
dispatch for :child-data
, should I grab data from the state? I don't want to seach for :child-data
key in the whole tree of the state data@ag I'm not sure I understand what you want explained. But perhaps this is a time to call the parser recursively from :main-data read fn? I assume you are asking about reading the client state after getting data back from the server and merging that novelty in.
@cmcfarlen: I am calling the parser recursively from :main-data’s dispatch, and when it sends to fetch data, it does ignore :main-data
part, since I actually care for :child-data
. When server returns it, it puts it into the state. and that seems to be working fine
but, if I need some additional logic in my read for :child-data
, like filtering based on params, I need to grab it out of the state
but it’s now sitting in {:main-data {:child-data
… if I wrap it into more complex query: it might end up being in {:main-data {:sub-main-data {:child-data
@ag you could add additional data to the env to note the path you've visited in the state as you call the parser recursively. But you could also use the query parameters to parameterize your reads. Those then show up in the third argument to the parser fn.
@cmcfarlen: oh, right, from :main-data
where I call the parser recursively, right… I’m gonna try that. Thanks
What's the correct lifecycle method in om.core
to hook to notice when a component's state changes? I tried implementing will-update
, but next-state
is the same as (om/get-state owner)
, so there doesn't appear to be a way to get the previous state.
@peeja: maybe get-rendered-state
in will-update
? https://github.com/omcljs/om/blob/master/src/main/om/next.cljs#L604
Looks like theres a get-render-state
in Om now: https://github.com/omcljs/om/blob/master/src/main/om/core.cljs#L1343
when interactive developing sometimes I mess up and write bad code and get an exception, this seems to break figwheel/react until the browser is refreshed
for example I wrote some code that generated this exception "react.inc.js:18893 Uncaught Invariant Violation:" and from this point onward figwheel stops being able to hot reload the code