Fork me on GitHub
#om
<
2016-09-21
>
peeja02:09:39

The more I think about it, the more I think I don't understand how Om Next is supposed to work…

peeja02:09:36

Am I correct in thinking that idents in the app state are meant to be an implementation detail of normalization?

peeja02:09:44

Actually, the more I think about it, the more I realize there's less "supposed to" than i expected. 🙂

hlolli12:09:17

should (om/react-key (dom/div #js {:key :somekey})) not return :somekey?

grzm15:09:05

Is there a way to clear/reset om's history? When a user logs out of the app I want to make sure I reset the application state.

hlolli15:09:25

make a mutation that resets the app-state, perhaps on componentWillUnmount? or logout :onClick ?

grzm17:09:27

hlolli updating the app state I can do. Looks like clearing the history in the reconciler should be pretty straightforward, too.

peeja18:09:02

Om Next's notion of "parent" is actually React's notion of "owner", is that correct?

peeja18:09:50

That is, it's not based on the rendered tree, it's based on the tree of who builds which components

peeja18:09:19

So if you build a component and build a second component you pass into the first, you're the Om parent of each

liamd19:09:09

wrapping my head around om.next. Is the parser a combination of redux’s selectors and reducers? Specifically mutate fn = reducer and read fn = selector? or are they fundamentally different?

liamd19:09:59

i suppose the queries are much more flexible than selectors and are co-located in the component. but transact! seems similar to dispatch

dnolen19:09:36

@liamd query concept is just lifted from Relay not Redux

dnolen19:09:16

however yes there is of course some conceptual overlap with Redux due to the functional approach

dnolen19:09:26

@peeja it is based on the render tree as that’s the way we propagate that information - it’s possible we could do it via the React context stuff, but I haven’t looked into that

peeja19:09:59

Is it? It looks like it's based on dynamic binding.

dnolen19:09:16

it is but dynamic binding doesn’t work async

dnolen19:09:22

rendering isn’t async

dnolen19:09:34

and that’s where we establish the binding

peeja19:09:42

So, if A builds B and C, passing C into B and returning B from its render, and then B wraps C in a div, who's the parent of C?

peeja19:09:57

A built it, but B is its closest ancestor in the DOM

dnolen19:09:27

you can answer all these questions by thinking about what I said

peeja19:09:45

Okay, that's pretty condescending, honestly

peeja19:09:00

I have thought about all of this, and read through the code, and found it surprising

dnolen19:09:05

you can interpret it that way if you like

dnolen19:09:14

or assume I’m being brief because of time

dnolen19:09:34

@peeja RE: the AST stuff, :query is a convenience

dnolen19:09:49

you’ll want to discard it if you’re doing something fancy

dnolen19:09:28

I’m unaware of any sophisticated users of AST so have had limited feedback about that

peeja19:09:42

That makes sense

peeja19:09:27

From what you're saying and from the code I'm reading, my understanding is that A is the parent of C. Is that correct?

dnolen19:09:07

just think about binding

dnolen19:09:17

there’s no need to consider anything else

dnolen19:09:24

if you build in some strange way, yes it won’t work

peeja19:09:38

That's not strange, that's just higher-order components

peeja19:09:49

That's a significant part of using React

dnolen19:09:06

I don’t really think that it is

dnolen19:09:15

and you can make it work if you like

peeja19:09:22

You're saying it's strange to pass children to a component?

dnolen19:09:38

I don’t think it matter’s much

dnolen19:09:58

still I understand the attraction

peeja19:09:59

Okay: I have old Om components and Om Next components. I need them to render each other sometimes. I also have native React components occasionally, and a bunch of functions which pretend to be components but are just functions that return React elements. I need to make sure I'm not screwing this up.

dnolen19:09:14

if there’s a way to thread the relationship via some other means more realiable in React then I’m open to the idea

peeja19:09:39

I'm specifically not asking you to think through all of that for me, I'm trying to respect your time by asking a very straightforward question to validate my own conclusions.

dnolen19:09:41

I don’t know what you’re trying to do

peeja19:09:53

I'm not saying that what Om does is wrong, I'm just clarifying that it represents what React refers to as "ownership", while React's notion of "parenthood" is based on the DOM tree.

dnolen19:09:57

we did relax the transact! case, so maybe some things will just work

dnolen19:09:14

React ownership isn’t changed

dnolen19:09:18

it’s all just React

dnolen19:09:31

the om.next notion of parent is something else entirely we use for other stuff

peeja19:09:53

I'm not saying React's ownership changes, I'm saying that Om calls something "parent" which corresponds to React's notion of "owner" and not to React's notion of "parent".

peeja19:09:11

That's not bad, I just want to make sure I'm correct in coming to that conclusion.

dnolen19:09:15

@peeja but I don’t know why this matters?

peeja19:09:02

Because I have to muck with Om internals to get the parent chain to work properly here, and I want to make sure I'm doing the right thing.

peeja19:09:21

I have to capture the correct dynamic vars when building an om.core component, keep them in the shared map, and then rebind them when I start rendering om.next components again.

peeja19:09:26

(and the same in reverse)

peeja19:09:41

AFAICT, that's the only reasonable way to migrate an app from om.core to om.next.

dnolen19:09:03

well we’re talking about too many different for me at the moment (om.core -> om.next)

dnolen19:09:25

but still, having to fix the parent chain is a bit ugly

dnolen19:09:48

we could instead have this be a stateful field that’s set when we have the info

dnolen19:09:06

I don’t know how much work that is - but probably not too hard?

dnolen19:09:36

happy to see someone work on that - at first glance I don’t see how it could cause any real problems

peeja19:09:55

When you say "stateful", where do you see that state living?

dnolen19:09:07

just put it on the instance

dnolen19:09:32

or on state which is wrapper around raw React state already

dnolen19:09:54

but my impression is that the first thing should work

dnolen19:09:13

so it’s just a lazy field set after mounting

dnolen19:09:36

the primary problem is we don’t care about random React components

dnolen19:09:49

we only care about parents invovled in queries

peeja19:09:11

Right, but the parent chain already has non iquery?s in it, and they're filtered out

peeja19:09:15

so that should be okay

dnolen19:09:31

but you don’t control React components

dnolen19:09:35

how will you propagate?

peeja19:09:53

Oh, yeah, no I don't have a solution for that

dnolen19:09:06

so Relay must have solved this - probably with non-public hacks

dnolen19:09:15

anyways I didn’t have time to look into it

peeja19:09:28

As you said earlier, context might work, but context stuff has been changing a lot

dnolen19:09:28

and I didn’t really see higher order components as the end-all be-all

dnolen19:09:36

i.e. multimethods work just fine for composition

dnolen19:09:44

with delayed decisions

peeja19:09:56

To be clear: I don't actually need higher-order queried components

peeja19:09:11

I just need higher-order dumb components not to break the query chain

dnolen19:09:25

because they will hold something with a query?

peeja19:09:30

That's right

peeja19:09:38

Which should be fine

dnolen19:09:46

right so that’s higher ordered query components far as I’m concerned 🙂

dnolen19:09:56

anyways I think you understand why it is the way that is

dnolen19:09:02

if you have brilliant ideas I’m listening

peeja19:09:52

Wait, why are those higher-ordered queried components?

peeja19:09:11

For instance: We've got a component that builds a card (visually)

peeja19:09:28

I want to wrap this Person component in a Card component

peeja19:09:33

Person has a query, Card doesn't

peeja19:09:05

I build the Person and the Card, and pass the Person into the Card to render

peeja19:09:18

I build the Person with props from my props

peeja19:09:29

I build the Person within my render, so I'm the parent

peeja19:09:53

So there should be a correct chain from me to the Person that doesn't care about the Card component at all

dnolen19:09:16

I don’t think this part is all that relevant to the bigger point 🙂

peeja19:09:34

Then I think I'm missing the bigger point 🙂

peeja19:09:36

What is it?

dnolen19:09:45

I’ve explained the issue

dnolen19:09:52

what are you still misunderstanding?

dnolen20:09:07

the jargon doesn’t matter it seems to me

peeja20:09:38

Oh, you're saying for the migration case, rather than the higher-order case

dnolen20:09:02

no, I don’t want to talk about the migration case - that’s downstream

peeja20:09:10

Then I'm lost

dnolen20:09:12

the higher-case I’ve explained why it doesn’t work

peeja20:09:25

I just explained why it does work, though…

dnolen20:09:32

that’s all that matters - then you can solve your subproblem

dnolen20:09:03

it doesn’t work

dnolen20:09:25

parent gets set when invoking the factory based on the bindings in place

peeja20:09:45

Right. And the factory is not invoked by the higher-order component

peeja20:09:57

It's invoked in the render of the correct component

dnolen20:09:57

are we repeating ourselves here?

peeja20:09:07

Yes, but we're coming to opposite conclusions 🙂

dnolen20:09:29

you compose B with C in A’s render

dnolen20:09:32

both will have parent A

dnolen20:09:50

that’s not what you want

peeja20:09:53

Sure it is

dnolen20:09:54

A -> B -> C

peeja20:09:58

Why wouldn't you want that?

peeja20:09:12

C's query is composed directly into A's

peeja20:09:22

Its data path runs A -> C

dnolen20:09:24

they all have queries

dnolen20:09:32

it won’t work

peeja20:09:39

Why would you have a higher-order component with a query?

dnolen20:09:52

why wouldn’t you?

peeja20:09:09

Because I can't imagine how it would be useful

dnolen20:09:21

why do you believe that?

peeja20:09:45

M-x doctor

peeja20:09:13

How would you compose the query?

peeja20:09:22

What could A's query look like?

dnolen20:09:21

this is assuming there’s only one way to compose the query

peeja20:09:29

I mean, you could have a B with a query, but it would have to be independent of C's query anyway, right?

peeja20:09:40

You'd still want the parent of each to be A

dnolen20:09:41

once you disabuse yourself of that idea then you see you might want to do this

dnolen20:09:07

nothing about Om dictates how the queries are composed or resolved

peeja20:09:09

Can you actually come up with a use case to demonstrate how it would be useful?

dnolen20:09:09

it’s just a function

peeja20:09:22

Wait, that's not accurate

dnolen20:09:33

anyways I can’t do a brain dump right now

dnolen20:09:38

sorry, gotta get back to work

peeja20:09:40

Om requires you to compose queries in a specific way to maintain the correct metadata

dnolen20:09:57

the default does

dnolen20:09:06

but you can replicate that however you feel like it

peeja20:09:53

I see what you're saying. I'd love to see a use case someday to validate its utility, but I get what you mean.

peeja20:09:24

In any case, the good news for me is that this means there's no problem with what I'm doing. So… 🎉

peeja20:09:33

Thanks for talking it through