Fork me on GitHub
#om
<
2016-08-11
>
grzm16:08:39

I'm debugging what looks like a server-side transit encoding issue. While debugging, I want to create an edn literal that includes an #C06DT2YSY/id tagged literal. Here's what I'm trying:

(def edn-body
  {some/new-item {:tempids {#om/id["2e486bfc-aacb-4736-8aa2-155411274e84"] 852154481843896390}}})
When I do so, I'm getting No reader function for tag om/id Is there a way to quote this so the compiler ignores it? Or include a reader?

peeja17:08:57

It looks like componentWillReceiveProps receives a next-props that doesn't include children. Is that right? And if so, what's the correct way to get the incoming children?

chris-andrews17:08:34

@grzm You might want to check in the #C03S1L9DN channel for more info about readers. I don’t think you can quote literals; they need to be defined

chris-andrews17:08:04

@peeja what are you trying to do with the incoming children in componentWillReceiveProps?

peeja17:08:32

Store them in state to delay their appearance

chris-andrews17:08:08

these are the child components, not props?

chris-andrews17:08:27

(not too familiar with the what children are in om)

peeja17:08:48

In React, children is just another prop

peeja17:08:10

It's specified in a special way when you create the element, but it comes in as this.props.children

peeja17:08:44

But Om appears to pull it out, and then doesn't give you a way to access it before it's available as (om/children this)

chris-andrews17:08:19

Not sure how much this helps, but I think componentWillReceiveProps behaves a bit differently in om.next than react

peeja17:08:02

So, is there a way to get the incoming children?

peeja17:08:52

I thought one of the great things about om.next was that you had access to the real React lifecycle

chris-andrews17:08:58

You can access them, but you might not be able to rely on setting state in response to the incoming children like you’re after

chris-andrews17:08:53

There are other people here who probably know this better than me, but my understanding in the past at least was that the lifecycle is slightly different because om.next renders asynchronously and batches changes

peeja17:08:20

Oh, wow, it does? It takes over the render cycle?

chris-andrews17:08:57

I think it does to some degree, and I think that means that setting state in your lifecycle isn’t quite the same as how it works in react

chris-andrews17:08:16

I believe there was talk about removing componentWillReceiveProps at one point for this reason

peeja17:08:41

Yikes. Okay…is there a better way to write a React-like component?

chris-andrews17:08:52

because it basically exists in react so that you can set state and guarantee that your state will be updated properly in time for the rest of the lifecycle

peeja17:08:14

This isn't an iquery?, it's a dumb component which handles some visuals

peeja17:08:40

I thought the correct way to handle that was to use defui and only implement the lifecycle methods

peeja17:08:47

but maybe even that's inappropriate

chris-andrews17:08:33

You can rely on the lifecycle methods being called in the right order and everything, but the local state in om is just a bit different

chris-andrews17:08:04

My workaround was just to put an atom in local state and swap! the value in the lifecycle

peeja17:08:22

Oh, I'm not too concerned about that, then, I think. I'm actually going to be pushing it into a core.async channel

peeja17:08:58

Well, that's not entirely accurate. When it comes out of the channel, the element will have to go into the state to be rendered

chris-andrews17:08:09

So the impression I got was that when you call the om functions to update state, they are really queuing that state update, and it seemed like you might not be able to count on state and props updating in lock-step like with react

chris-andrews17:08:02

I think you should be able to accomplish what you need by using the lifecycle but just staying away from om/set-state or whatever the exact fn name was

peeja17:08:26

That actually shouldn't be a problem for me: I need a props update (new children) to give me a chance to put the new child in a channel, and when I pull it off the channel I need to put the child in the state and cause it to render. Getting state and props to update in lockstep doesn't matter to me.

peeja17:08:40

I just need to access the children from the props at all

peeja17:08:53

Maybe I should be using componentWillUpdate instead?

chris-andrews17:08:16

yeah, basically the other lifecycle methods ended up being my go-to

anmonteiro17:08:16

@peeja: Om Next renders incrementally in some cases, which means that componentWillReceiveProps will not be called in those cases

anmonteiro17:08:56

There's a patch to address this that is waiting to be merged

anmonteiro17:08:37

To be clear, componentWillReceiveProps is currently only called when rendering from the root

chris-andrews17:08:07

oh, thanks for clarifying that

anmonteiro17:08:14

So I would first check if it is being called at all

anmonteiro17:08:31

Only then try to get at the children

peeja17:08:58

Well, it is, but I'm not using an Om Next reconciler ATM

peeja17:08:11

This component is in an om.core app, for now

peeja17:08:46

What does rendering incrementally mean in Om Next? I saw some mention of that, but I assumed it was about compatibility with React Fiber.

anmonteiro17:08:01

Rendering incrementally means that only the subtree rooted at the transacting component will be re-rendered

anmonteiro17:08:54

Along with any other places in the app that query the same data

peeja17:08:07

In which case the transacting component wouldn't get componentWillReceiveProps, but its children would, right?

anmonteiro17:08:22

Queries + the indexer give us the knowledge to do this

anmonteiro17:08:32

@peeja: yes that's right

peeja17:08:45

That's fine, then; this component isn't iquery?

anmonteiro17:08:26

My proposed patch addresses just that: https://github.com/omcljs/om/pull/743

anmonteiro17:08:03

@peeja: right so if you're not using an Om Next reconciler you shouldn't be worried about these problems

anmonteiro17:08:38

Because even though you have an Om Next component you're using om.core's rendering loop

peeja17:08:38

Right, all I'm looking for is a way to be notified when my component's children change

peeja17:08:54

just as I can see when other props change

peeja17:08:47

React gives you nextProps.children, but there's nothing in Om's next-props

anmonteiro17:08:13

I don't think there's an obvious way to do that

peeja17:08:22

Is that intentional?

anmonteiro17:08:29

Probably not

peeja17:08:34

:thumbsup:

anmonteiro17:08:45

@peeja: you might want to open an issue to track that, but I'm not entirely sure how to solve that one in a clean way

anmonteiro17:08:30

Probably have the children be a computed property in next-props, not sure

anmonteiro17:08:09

I'm also not in front of a computer so can't really look at that right now

peeja17:08:38

That would make sense to me.

calvis18:08:05

is there a tempid guide/documentation somewhere? it’s not “Just Working” and I have no idea how to debug

grzm18:08:44

@chris-andrews: It's actually on the server side. I ended up using the tempid constructor rather than the reader literal.

anmonteiro18:08:38

@calvis: that one is really just an example to prove it works I've got a complete working example with a Datomic backend here: https://github.com/anmonteiro/talks/tree/master/2016-berlin-meetup

calvis18:08:25

@anmonteiro: thanks I like how minimal that is — is :id-key required? what if I had tempids for multiple idents coming back

anmonteiro18:08:06

id-key is required and is normally the thing by which all your entities are identified

anmonteiro18:08:26

Usually :db/id

calvis18:08:39

I’m not using a datomic backend so :db/id doesn’t make sense

anmonteiro18:08:44

I don't think there's a way around that

anmonteiro18:08:04

@calvis: probably worth having the same key for all your IQuery components so that tempid migration can work

anmonteiro18:08:15

Actually there's probably a way around that

calvis18:08:26

yeah, I don’t have that issue atm (just one ident) just kind of wondering about the restrictions

anmonteiro18:08:44

You'd need to override :migrate in the reconciler

calvis18:08:07

yeah that wouldn’t be so bad

calvis18:08:24

just break apart the tempids and call the default migrate with different id-keys

calvis18:08:48

that doesn’t seem to help though. I’m still seeing only my old ids

anmonteiro18:08:24

@calvis: is your state normalized?

calvis18:08:46

yeah it is in the reconciler

calvis18:08:09

so I copied om/default-migrate into my repl and checked the intermediate values, the call to db->tree returns a denormalized state with only the old tempids even though the pure’ expression has the new ones

grzm18:08:37

anyone know of a command line tool to pass edn to an Om server api?

grzm18:08:54

I'd like to test my API without needing to use a browser

anmonteiro18:08:23

@calvis: a number of things could be going wrong, happy to look at a minimal case though

calvis18:08:35

yeah I’ll put one together

calvis18:08:28

@anmonteiro: in case you’re curious, I was using two different keywords for the :keyfn and the first value of the ident vector, making them the same fixed the issue. is that bad style?

calvis18:08:51

or maybe my :id-key in the reconciler should have matched the :keyfn and it would have been fine

anmonteiro19:08:49

@calvis: :keyfn in factory should have nothing to do with it?

calvis19:08:43

@anmonteiro: I’m probably conflating things that don’t need to be conflated, I made an example: https://gist.github.com/calvis/31d895a924b888e8fff0e89d1cd7d8aa (essentially I picked the wrong :id-key)

jasonjckn21:08:57

how are the parent links setup (om/parent component)

jasonjckn21:08:15

for some reason when I enable simple optimizations some of my components fail to crawl the parent links and it leads towards null

jasonjckn21:08:43

these components IQuery aren't used/aren't aggregated by their parents IQuery, is that why?

jasonjckn22:08:05

is transact! on reconciler automatic root rerender?

jasonjckn22:08:17

full rerender of whole app?

jasonjckn22:08:49

i guess it does shouldComponentUpdate starting from the Root and crawls the tree (?)