Fork me on GitHub
#om
<
2017-03-08
>
sova-soars-the-sora06:03:59

@nha you need to make a serverside clone of your app-state-atom

petterik16:03:01

I construct the server-side clone of my app-state by running the client's parser on my server. This requires writing the reads in .cljc, You can see a server-side example here: https://github.com/anmonteiro/om-next-fullstack/blob/master/src/clj/todomvc/page.clj#L8 That line makes a reconciler which uses the client_parser reads: https://github.com/anmonteiro/om-next-fullstack/blob/master/src/shared/todomvc/todomvc.cljc#L80

levitanong16:03:05

@anmonteiro Currently, merge-tree does a naive merge of current app state and novelty. I think incremental remote updates that would require deeper merges without disturbing surrounding values (such as with pull to refresh within some nested list component) is something i expect a lot of people to do in the future, and therefore, enough to warrant om.next supporting this out of the box. I’m thinking of implementing a smarter callback by which selective deeper merges can happen. Is this something you think is worth exploring?

anmonteiro16:03:44

@levitanong merge-tree is naïve on purpose

anmonteiro16:03:53

I don’t think that’s gonna change

levitanong17:03:53

anmonteiro: I see. What is the reasoning behind this?

anmonteiro17:03:46

the reasoning is that people will have different needs and there remains to be seen what is the best default. In that case going with the simplest case, but allowing for extension, is IMHO the best you can do

levitanong17:03:35

I think with the current setup, merge-tree isn’t very extensible, as it can’t accept outside information. I tried attaching meta to the novelty hoping that I could include some :merge-paths information that i could use with assoc-in, but the meta is lost along the way.

levitanong17:03:13

Currently I manage with merge, but I’m looking for a more elegant way.

nha16:03:14

Not sure I explained correctly. My initial :state is an empty atom (client and server). I have a server-side reconciler and it calls the server reads and renders to a string fine. Then said string gets loaded on the page, fine again. Then om is mounted from the javascript, but it has no initial state. So it renders a first time without initial state and makes requests (not sure in which order). And then fetches data from the server (again in a way), and displays the same things it initially displayed. I would like to get rid of the un-necessary extra fetch, and more importantly the FOMD (flash of missing data) 😛

anmonteiro17:03:38

@nha the extra fetch is a harder problem, which I’ll leave for you to solve

anmonteiro17:03:00

the flash of missing data doesn’t make sense to me, as there are ways to avoid it

anmonteiro17:03:09

what version of Om are you using?

nha17:03:24

latest, I think alpha-48 (let me check)

anmonteiro17:03:02

so Om will not render if it’s waiting for a remote call

nha17:03:15

1.0.0-alpha47 exactly

nha17:03:19

Ah great 🙂 will try this evening at home.

nha17:03:13

However I am surprised there is no way to get the data from a component, as this sounds like something you would want in a a repl-driven workflow? How do people develop om components? Like JS components except with figwheel?

anmonteiro17:03:11

not sure what you mean

anmonteiro17:03:44

om.next/props will get you the data from a component

nha17:03:01

Right that part is good. It goes both ways: feed data, get it in props etc. I guess something else bothers me. I have to find words to put it still - something is not symmetric with the query mechanism like it is with the props. Could be lack of om knowledge on my end though.

nha17:03:19

I just feel that om components don’t compose quite like functions I guess.

wilkerlucio18:03:14

@nha if you are trying to inspect something during development time, you can use the React Tools on chrome to visually pick an element on screen (it will be $r on JS), with that you can get props with om.next.props($r), or anything else you want to do with the component

peeja19:03:20

@anmonteiro We're trying to navigate after a successful call to the remote server. Do you have any thoughts on how to do that in Compassus? I don't have access to the application in send, so I can't call set-route!. Although I could rearchitect it to close over the application when the app boots. Would that be appropriate?

peeja20:03:06

Should send be allowed to see the application/reconciler? Or should I be finding some way to pass a callback of some kind into the send for it to call after the response comes back from the server?

anmonteiro22:03:51

@peeja what do you need to do in send! that you can’t do in merge?

peeja22:03:35

@anmonteiro Oh, that's interesting.

peeja22:03:49

I want to know what mutation I'm completing, though, I think

peeja22:03:08

I really kind of want to know which component transacted it. Or, really, I want to component to decide what to do

bnoguchi22:03:09

Under what conditions might one expect (path component) be nil? Trying to track down an issue and finding that it's nil when called in default-ui->props in om src.

peeja22:03:23

I'm considering passing a callback as a param in the mutation

peeja22:03:25

The are a couple of use cases we've got: one is that when you successfully create something with a particular button I want to navigate you to that thing

peeja22:03:49

the other is that we want lots of buttons to show that they're "working" while the request is out

anmonteiro22:03:26

@peeja so at Ladder we use a function called normalize (I know, poor naming choice) that runs inside merge

matthavener22:03:35

bnoguchi: this may not be the case, but I’ve seen (path component) fail when rendering child components with map instead of mapv

matthavener22:03:55

only during advanced optimization though

anmonteiro22:03:19

in our case it’s a multimethod that dispatches on the mutation that just ran

anmonteiro22:03:40

we use it for the same use cases you’re talking about

anmonteiro22:03:58

i.e. redirecting to a route after a remote mutation returns, stopping to spin a loading button, etc

peeja22:03:29

Does merge know about the mutation?

bnoguchi22:03:53

@matthavener mapv? I'm using (apply dom/div #js {} (map child-factory items))

anmonteiro22:03:48

@peeja try to print out the novelty returned by a remote mutation

peeja22:03:42

Oh, from the query?

anmonteiro22:03:00

it will also be in the result returned by the server

peeja22:03:11

Oh, right, that makes sense

anmonteiro22:03:14

like {‘do/this! {:result ...}}

anmonteiro22:03:32

@peeja yea, I think you got everything you need

peeja22:03:47

How do you get the right button, though?

peeja22:03:02

Like, if you have two buttons that both do the same thing on the page and you click one, do they both spin?

anmonteiro22:03:32

well, depends what key they’re linked to in the app-state, doesn’t it?

anmonteiro22:03:39

do you want them both to spin? I would

anmonteiro22:03:55

since it doesn’t make sense to click one if you already clicked the other which does the exact same thing

peeja22:03:23

I guess that makes sense. I'll chew on it.

peeja22:03:27

Thanks! 🎉

matthavener22:03:33

bnoguchi: yeah, i was calling map instead of mapv (non-lazy). i think the map interacted with the dynamic vars that track the om.next path in weird ways. i didn’t really debug it much, though

anmonteiro22:03:35

you’re welcome

bnoguchi22:03:51

Hmm, still getting nil for (path c) when I swap in mapv

bnoguchi22:03:27

@matthavener Do you recall where that fn path is defined? Only one I could find was in om.core, but that seemed related to cursors and not imported to next.cljc

matthavener22:03:38

its defined in next.cljc

bnoguchi22:03:54

@matthavener thanks, not sure how I missed that

bnoguchi22:03:39

@matthavener Figured it out. The culprit was invalid query syntax (for a parameterized join). The parser could consume the invalid query and returned the expected read but the broken syntax broke how path works.

bnoguchi22:03:59

@matthavener Thanks for the help!

matthavener22:03:07

ahh, sure thing

matthavener22:03:22

I figured it probably wasn’t the ‘map’ thing when I realized you were also having the issue in dev 🙂