Fork me on GitHub
#om
<
2016-06-07
>
ag00:06:25

I don’t get it. In read method for a collection, it’s up to me to filter data based on query?

ag00:06:32

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?

ag00:06:31

my query [{:big-list-of-data [:name :id]}] doesn’t work otherwise

ag01:06:40

and same thing applies to params, I have to manually filter data

noonian01:06:41

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.

noonian01:06:29

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.

anmonteiro11:06:09

@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})

anmonteiro11:06:36

and in the component in which the transaction belongs, I call (om/transact! owner '[(tx)])

dobladez11:06:55

Thanks, that's good workaround

anmonteiro11:06:58

probably cleaner than passing callbacks here and there

dobladez11:06:02

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

dobladez11:06:37

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 ?!

anmonteiro11:06:34

every query must compose to the root, so in some recursive definition it always needs to know everything

anmonteiro11:06:05

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

anmonteiro11:06:16

so I’d take it with a grain of salt

dobladez11:06:18

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

dobladez11:06:50

so, the root's query would be something like [ {:root (om/get-query ItemList) } {:root (om/get-query FooList} ] . Makes sense?

dobladez12:06:00

@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

dobladez12:06:39

same thing when passing a reference to the owner

anmonteiro12:06:40

@dobladez: not everything needs to belong to the root, but it must compose to the root in a recursive sense

dobladez12:06:15

well... pretty much any top level "entity" would, right?

anmonteiro12:06:21

that’s right

anmonteiro12:06:25

also your little snippet isn’t quite accurate

anmonteiro12:06:34

your have 2 keys with :root

dobladez12:06:26

hmm... right.... so, I guess adding a level on indirection here does not really solve my problem 🙂

dobladez12:06:49

I would need one "fake root" key for each entity list

dobladez12:06:26

another dumb thing I tried was including the child query directly at the root with no join 🙂, like: [ (om/get-query ItemList) ]

anmonteiro12:06:46

right, that just won’t work

anmonteiro12:06:53

stealing queries is not allowed

dobladez12:06:52

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

peeja14:06:12

What's the difference between computed props and normal props? Why (om/computed props {:extra "stuff"}) rather than simply (merge props {:extra "stuff"})?

dnolen15:06:11

@peeja: because = on function values doesn’t work

dnolen15:06:37

so we want to be add event handlers onto the value we flow down without messing up equality checks

peeja15:06:59

Ah, of course. That makes sense.

peeja15:06:12

So, then, if you change only the handler, does the subcomponent not rerender?

dnolen15:06:18

@peeja yes that might be the case - I haven’t heard people complain about that one much yet

selfsame15:06:55

@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 _] [*]}]

peeja15:06:48

I suppose in my experience handler definitions tend to change at the same time the main props change, so that does sound right. Neat.

dnolen15:06:44

@anmonteiro: ha, I was only looking at shouldComponentUpdate

dnolen15:06:52

so then yes - probably somebody already complained about this

dnolen15:06:55

and it got fixed

peeja15:06:59

Then, is there a distinction?

dobladez15:06:22

@seflsame thanks!

selfsame15:06:30

@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

dobladez15:06:22

@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

peeja15:06:21

Yeah, I'm just not clear why that distinction is significant

peeja15:06:02

I mean, the semantics may still be WIP, and that's fair. I'm just wondering if I'm missing an important concept.

dobladez15:06:12

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?

selfsame15:06:25

yeah as long as meta is on the first arg

dnolen15:06:34

@peeja: OK now I remember

dnolen15:06:50

the problem is if a child changes it state (via changing query or whatever)

dnolen15:06:57

how can it get it’s event handlers

dnolen15:06:03

since they were given by the parent

dnolen15:06:23

so computed is way of saying here some stuff that needs to survive if the child changes it own state

peeja15:06:11

Ah, interesting. I'll need to chew on that… 🙂

peeja15:06:24

@anmonteiro: Cheers, that'll help

dnolen15:06:35

@peeja: it’s really only for event handlers

dnolen15:06:47

maybe somebody came up with another use case, but that’s what it’s for

dnolen15:06:46

well I suppose also synthetic stuff given to the child

dnolen15:06:50

not present in the query

dobladez15:06:45

excellent, thanks!

anmonteiro15:06:55

@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

peeja15:06:40

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?

anmonteiro15:06:49

that’s right

peeja15:06:57

That makes sense

peeja15:06:19

Ah, right

anmonteiro15:06:20

see it saves the computed props there

peeja15:06:01

So, computed values shouldn't depend on queried data, then (which I don't think is surprising)

peeja15:06:43

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)

anmonteiro15:06:49

in practice you’ll want to pass event handlers and style stuff

peeja15:06:16

Cool, that all makes sense

anmonteiro15:06:34

re: closing over there’s a discussion about that in the thread I linked

peeja15:06:43

And the reason this didn't matter until Om Next is that now we have a reconciler feeding the component new data directly

anmonteiro15:06:18

yeah I suppose that’s right

anmonteiro15:06:32

I don’t know how om.core did reconciliation but I think it relied on React

anmonteiro15:06:50

I might be wrong though!

peeja15:06:03

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. 🙂

peeja15:06:05

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.

peeja16:06:10

Is it only components with Idents that get params fed directly to them by the reconciler?

peeja16:06:33

or does the reconciler have other ways of connecting components with data from the state?

dnolen17:06:01

reconciler just looks for keys

dnolen17:06:06

an ident is a kind of key

ag19:06:26

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

dnolen19:06:58

@ag why do you need to search for it? Aren't you just going to pass it along?

cmcfarlen19:06:45

@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.

ag20:06:52

@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

ag20:06:48

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

ag20:06:09

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

ag20:06:26

so, how do I retrieve it right?

cmcfarlen20:06:51

@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.

ag20:06:56

@cmcfarlen: oh, right, from :main-data where I call the parser recursively, right… I’m gonna try that. Thanks

peeja23:06:05

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.

peeja23:06:28

Oh, I guess I could use did-update.

peeja23:06:48

om.core, not om.next 🙂

noonian23:06:12

Ah, my bad

peeja23:06:19

But yeah, that's pretty much what I need. It may not exist.

noonian23:06:59

I’m pretty sure Om’s concept of state is distinct from React’s own

jasonjckn23:06:30

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

jasonjckn23:06:48

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

jasonjckn23:06:32

"react.inc.js:18893 Uncaught Invariant Violation: Objects are not valid as a React child " maybe there's just some way to reset react each time figwheel loads new code

jasonjckn23:06:44

i guess I could try refreshing the Root as a first step