@nha you need to make a serverside clone of your app-state-atom
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
@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?
@levitanong merge-tree
is naïve on purpose
I don’t think that’s gonna change
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) 😛
@nha the extra fetch is a harder problem, which I’ll leave for you to solve
the flash of missing data doesn’t make sense to me, as there are ways to avoid it
what version of Om are you using?
latest, I think alpha-48 (let me check)
so Om will not render if it’s waiting for a remote call
1.0.0-alpha47
exactly
can you try alpha48 which has this fix https://github.com/omcljs/om/commit/b8922e98a7bec8e446d68419b9ef226e4e4f74f8
Ah great 🙂 will try this evening at home.
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?
not sure what you mean
om.next/props
will get you the data from a component
anmonteiro: I see. What is the reasoning behind this?
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
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.
I just feel that om components don’t compose quite like functions I guess.
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.
Currently I manage with merge
, but I’m looking for a more elegant way.
@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
@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?
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?
@peeja what do you need to do in send!
that you can’t do in merge
?
@anmonteiro Oh, that's interesting.
I want to know what mutation I'm completing, though, I think
I really kind of want to know which component transacted it. Or, really, I want to component to decide what to do
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.
I'm considering passing a callback as a param in the mutation
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
the other is that we want lots of buttons to show that they're "working" while the request is out
@peeja so at Ladder we use a function called normalize
(I know, poor naming choice) that runs inside merge
bnoguchi: this may not be the case, but I’ve seen (path component)
fail when rendering child components with map
instead of mapv
only during advanced optimization though
in our case it’s a multimethod that dispatches on the mutation that just ran
we use it for the same use cases you’re talking about
i.e. redirecting to a route after a remote mutation returns, stopping to spin a loading button, etc
Does merge
know about the mutation?
@matthavener mapv
? I'm using (apply dom/div #js {} (map child-factory items))
sure does
@peeja try to print out the novelty returned by a remote mutation
Oh, from the query
?
it will also be in the result returned by the server
Oh, right, that makes sense
like {‘do/this! {:result ...}}
Sweet!
@peeja yea, I think you got everything you need
How do you get the right button, though?
Like, if you have two buttons that both do the same thing on the page and you click one, do they both spin?
well, depends what key they’re linked to in the app-state, doesn’t it?
do you want them both to spin? I would
since it doesn’t make sense to click one if you already clicked the other which does the exact same thing
I guess that makes sense. I'll chew on it.
Thanks! 🎉
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
you’re welcome
Hmm, still getting nil for (path c)
when I swap in mapv
@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
its defined in next.cljc
@matthavener thanks, not sure how I missed that
@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.
@matthavener Thanks for the help!
ahh, sure thing
I figured it probably wasn’t the ‘map’ thing when I realized you were also having the issue in dev 🙂