om

Please ask the channel first, not @dnolen directly!
sova-soars-the-sora 2017-03-08T06:26:59.005207Z

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

petterik 2017-03-08T16:42:01.005210Z

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

levitanong 2017-03-08T16:53:05.005213Z

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

anmonteiro 2017-03-08T16:57:44.005216Z

@levitanong merge-tree is naïve on purpose

anmonteiro 2017-03-08T16:57:53.005217Z

I don’t think that’s gonna change

2017-03-08T16:58:14.005218Z

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) 😛

anmonteiro 2017-03-08T17:01:38.005222Z

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

anmonteiro 2017-03-08T17:02:00.005223Z

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

anmonteiro 2017-03-08T17:02:09.005224Z

what version of Om are you using?

2017-03-08T17:02:24.005225Z

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

anmonteiro 2017-03-08T17:03:02.005227Z

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

2017-03-08T17:03:15.005228Z

1.0.0-alpha47 exactly

anmonteiro 2017-03-08T17:03:55.005229Z

can you try alpha48 which has this fix https://github.com/omcljs/om/commit/b8922e98a7bec8e446d68419b9ef226e4e4f74f8

1
2017-03-08T17:04:19.005231Z

Ah great 🙂 will try this evening at home.

2017-03-08T17:05:13.005232Z

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?

anmonteiro 2017-03-08T17:06:11.005234Z

not sure what you mean

anmonteiro 2017-03-08T17:06:44.005235Z

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

levitanong 2017-03-08T17:06:53.005236Z

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

anmonteiro 2017-03-08T17:07:46.005238Z

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

2017-03-08T17:11:01.005240Z

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.

2017-03-08T17:11:19.005241Z

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

levitanong 2017-03-08T17:12:35.005242Z

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.

levitanong 2017-03-08T17:14:13.005245Z

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

wilkerlucio 2017-03-08T18:56:14.005247Z

@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

peeja 2017-03-08T19:59:20.005249Z

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

peeja 2017-03-08T20:00:06.005250Z

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?

anmonteiro 2017-03-08T22:14:51.005251Z

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

peeja 2017-03-08T22:20:35.005252Z

@anmonteiro Oh, that's interesting.

peeja 2017-03-08T22:20:49.005253Z

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

peeja 2017-03-08T22:21:08.005254Z

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

2017-03-08T22:21:09.005255Z

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.

peeja 2017-03-08T22:21:23.005256Z

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

peeja 2017-03-08T22:22:25.005257Z

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

peeja 2017-03-08T22:22:49.005258Z

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

anmonteiro 2017-03-08T22:23:26.005259Z

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

matthavener 2017-03-08T22:23:35.005260Z

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

matthavener 2017-03-08T22:23:55.005261Z

only during advanced optimization though

anmonteiro 2017-03-08T22:24:19.005262Z

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

👍 1
anmonteiro 2017-03-08T22:24:40.005263Z

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

anmonteiro 2017-03-08T22:24:58.005264Z

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

peeja 2017-03-08T22:25:29.005265Z

Does merge know about the mutation?

2017-03-08T22:25:53.005266Z

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

anmonteiro 2017-03-08T22:25:54.005267Z

sure does

anmonteiro 2017-03-08T22:26:48.005269Z

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

peeja 2017-03-08T22:27:42.005270Z

Oh, from the query?

anmonteiro 2017-03-08T22:28:00.005271Z

it will also be in the result returned by the server

peeja 2017-03-08T22:28:11.005272Z

Oh, right, that makes sense

anmonteiro 2017-03-08T22:28:14.005273Z

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

peeja 2017-03-08T22:28:17.005274Z

Sweet!

anmonteiro 2017-03-08T22:28:32.005275Z

@peeja yea, I think you got everything you need

peeja 2017-03-08T22:28:47.005276Z

How do you get the right button, though?

peeja 2017-03-08T22:29:02.005277Z

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

anmonteiro 2017-03-08T22:29:32.005278Z

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

anmonteiro 2017-03-08T22:29:39.005279Z

do you want them both to spin? I would

anmonteiro 2017-03-08T22:29:55.005280Z

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

peeja 2017-03-08T22:30:23.005281Z

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

peeja 2017-03-08T22:30:27.005282Z

Thanks! 🎉

matthavener 2017-03-08T22:30:33.005283Z

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

anmonteiro 2017-03-08T22:30:35.005284Z

you’re welcome

2017-03-08T22:31:51.005286Z

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

2017-03-08T22:34:27.005287Z

@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

matthavener 2017-03-08T22:37:38.005288Z

its defined in next.cljc

2017-03-08T22:39:54.005289Z

@matthavener thanks, not sure how I missed that

2017-03-08T22:49:39.005290Z

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

2017-03-08T22:49:59.005292Z

@matthavener Thanks for the help!

matthavener 2017-03-08T22:50:07.005293Z

ahh, sure thing

matthavener 2017-03-08T22:50:22.005294Z

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