Fork me on GitHub

repost from #om Did anynoe attempt routing in om-next in react-native using the navigator-redux components?


@dzannotti are you sure that you need routing in RN?


@savelichalex I guess not in the strict sense of url routing, but yeah you need to control the navigation stack, and pass props around (like an item view screen would need the itemid passed from parent)


rn has NavigatorExperimental which allows controlling of the routing navigator stack from a reducer redux style, but i'm not sure how to integrate that with om-next, or better, the only thing i can think of is to use om/add-root! but i'm pretty sure that's a bad idea


@dzannotti just don't think that it will work, just first see how do this in RN


right now i'm using react-native-navigation and this is does not seem to similar on web


@dzannotti and as I know, NavigatorExperimental is steel unstable


it's stable, but api changes slightly at times, most quirks are ironed out by using react-native-router-flux over the RN api. but anyway the question applies to react-native-navigation too


how do you set the query for the current view?


I'm not familiar with om well, don't understand what you mean by query


the component query


(it's way of describing the component requirements state wise)


@dzannotti I’ve been using NavigatorExperimental with my RN app. See: It uses reagent, but the principles are the same. Just implement the mutations on the navigation stack. see onwards


@levitanong oh that's awesome thanks, my only concern is how to tell that the current query has changed (since i'm displaying a different route), how did you implement that?


dzannotti give the reconciler a set-route mutation fn that change current route in the app state this way the reconciler will schedule-render when the route change...


@sineer yeah but how does the reconciler knows which one is the root query if the root in reconciler doesn't have that query?


the root component for the reconciler is the router


@dzannotti you need an om-next component (i.e. defui NavRoot). In my experience using @exponent/ex-navigation awesome navigator, the navigator takes care of pushing/poping scenes for me and I have the reconciler re-render components independently when their query's data changes... I'm still trying to figure it all out btw so don't take what I say for granted 😉


@sineer totally, me too 🙂 do you have an example on GH i could look at/take inspiration from?


(aka read-understand-copy :D)


Not yet. I hope to pull out some stuff later when the dust settles...


I think you'll learn more by experimenting with it yourself too 😉 I learned a lot about how om next worked by doing that.. forced me to read om next code and figure stuff out 🙂


Also, if you are interested in lymchat, I made an template(support both om next and re-frame):


tiensonqin nice! It is very similar to what I do in om next using mutation FN for :nav/pop and :nav/push


I'm still learning about it, but it works pretty well!


The hard part for me was how to instantiate the routes components using om next factory and wrapping that in thunk/closure fns for the navigator router's routes map...


yep i was gonna say, it's great, but re-frame does not have the queries to pass around


but thanks @tiensonqin, now i got something to read 😄


Uhm.... that part that you just linked, could tie quite well, with the compassus ideas actually


@dzannotti you're welcome, om-next is awesome, like the declarative queries, normalization, stuff...


I now need to find a time machine to have more hours in the day to do some digging/experimenting around 😄


@dzannotti I too have a feeling that compasses might be tweaked to do routing on RN but Im in the same boat having already spent lots of time playing around. I came to the early conclusion that implementing something simpler might be smart but the thing is I'll soon have to implement login/auth and to that end I think compassus could be useful I think.


and later on I want my app to have the web version live along RN version so I can see how a "united" routing strategy would kick ass..


Yeah i want to implement the auth part right off the bat since i don't really have production needs, but just playing around. But i think that part isn't totally tied into the routing itself (as in you can just not go remote unless you are already logged in), i don't think that mobile navigation is that far apart from web one, beside direct visits. Reinventing the wheel seems un-necessary time wasted


indeed. Compasses mixins looks perfect to implement auth and much more. I will have to find the time and learn to use it, better now than later I guess! Maybe I will implement login/auth now and close the loop on my nav/routing strategy tonight


Ive kinda ported the om-next-datomic-datascript-todomvc demo to RN. I still have more work todo like migrating tempids properly and more UI stuff but overall it works and I got server sent event stop work with RN is very cool imho


@sineer Didn’t you have any performance issues with datascript? I remember multiple attempts with datascript + RN in this chat but performance was a problem often


I haven't got around implementing the todos benchmark but so I have no idea yet how it would handles 100s of todos..


@misha are you using datascript + RN still? As far as I remember you were using it


@dzannotti I having a third glimpse @ compassus and I just saw that he has an elegant solution to have the parser dispatch on component(s) query instead of current route by simply passing :route-dispatch false " If set to false, the parser will not dispatch on the current route, but instead on the query of the component pertaining to that route"


I think if I can use compassus's router with ex-navigation together it would work 🙂


I mean, when I change route the navigator would have the reconciler parse the components query instead of the current route.


Earlier I thought I'd have the route query parse the components query but that would mean lots of poutine code I dont need. I want to have compassus dispatch on BOTH the current route (to keep track of history on remote as well as local) and the components query for updates.


@artemyarulin I do. but I do it from react native module via dreadful api


are you using it with om or rum, I don’t remember?


oh nice, like it? any issues with RN integration?


does not really matter which wrapper it is, as far as performance is concerned


rum? no. some one added rum to re-natal template, and that sorts out most (all?) of black magic required to use it


right now I am wrestling with the data flows, forms and stuff (given DS behind async API), and am considering having a look at om-next when I sort out business logic workflow (for the data normalization, and queries purposes).


I am doing something similar now as an experiment – maintaining cache harold of datascript db with a bi-directional subscription to changes.


this way you have data in DS for normalization and super easy server sync, + instant UI updates, because mutations are done to cache, not DS


but I have yet to see how it'll go on a larger scale


didn’t understand a thing but sounds cool 🙂


@dzannotti apologies for the really late reply, had some social things to do. With NavigationExperimental, unless you want to do a lot of code, you should probably use NavigationCardStack, which exposes the current navigation state to its renderScene (not sure if this is the exact method, but you get the idea). The shape of your navigation state in your app state will be something like:

{:index 0
 :routes [
    {:key “home” :title “Home” :some-other-field 2}
    {:key “profile” :title “Profile” :another-arbitrary-field “cow”}]}
Each of the routes will appear in your navigationCardStack as a javascript object, of the shape:
  {route: {key: “home”, title: “Home”, someOtherField 2}
   index: 0}}
And you can just extract the key (.. props -scene -route -key) and do a case on it to render some other view.


No worries, i'm in no rush


i know how NavigatorExperimental works, used it plenty times before, the part i'm not sure is how to tie it up with om-next reconciler, rather to let the reconciler know that the root query changed


just include the navigation state in your query 🙂


static om/IQuery
(query [this]
  [:some/data :other/data :app/nav])


and in your transact, if your mutation doesn’t cause :app/nav to refresh, just include :app/nav explicitly, like so:

(om/transact! this
  `[(nav/push ~{:route {:key “new-view” :title “Herp}})


Uhm.. this maybe more an related question than navigation, but my understanding was that you need to compose the current query, from root component


so if the view changes, the root query itself changes


(adding :app/nav to the query only lets me pick up the current route props)


am i understanding it wrong?


Hmm… It sounds almost as if you’re talking about query-params, and you’re storing the current route as a value in query-params


the only time the query itself changes is if you have query-params in play. Otherwise, only the result of the query will change in response to changes in the app-state


Perhaps to better understand where you’re coming from, why is getting current route props insufficient?


Uhm... no i mean, let's say that have 2 route components (Foo, and Bar) one has query [:app/foo] and the second one has [:app/bar], let's assume that Foo is the landing page, and from there i can go to Bar, the initial root query is [:app/foo] but when i'm in Bar route, the root query needs to be [:app/bar]


so the reconciler needs to know that the current query changed based on route itself


my guess is that the best way to do this is as you suggested to transact on route change, and have a root component that changes its query with set-query! based on current route


Ah, I see. You’re working on multiple root components, like in compassus. What I do is only use one root component, so I include both queries in. [:app/foo :app/bar]


along with :app/nav


In my head each view pushed into the stack, should be pretty much a root component, this simplifies composing queries, am i thinking it wrong?


Hmmm… the way I think of the nav stack is mostly a parent-child thing. From a list of children, if I want to see a specific child’s details, I’d push that to the stack. The reason being is I want to easily pop and go back up to the list of children. I’m sure my interpretation is a narrow one, and that there are many other ways of using RN’s nav stack


I think that each pov is important, both because of different use cases, and both for the community to learn (hence why i was curious about your approach on this)


@dzannotti I was thinking the same prior to understanding that the route themselves are route components but in my latest iteration the Nav itself is the root component, also I didn not see how one could handle more than one root component in RN..


I mean route are om components


built using om/factory so they get passed the reconciler and register as child of root component that is the Nav itself..


The reconciler will know how to refresh only the child(s) that need refresh based on their query


that was why I was pointing out the option in compasus to call the parser with the route component's query rather than the current route


On the how, i have a rough idea (you could have om-next root as child of the navigator basically or something like that, but i'm not 100% sure that is a good idea, after @levitanong's interpretation, which i'm growing to like


I gotta run taking care of some plants but I'll be back later to discuss that further I'm really glad to have someone to talk to about all that sutff 😉


in my design the Nav is the om root component and the route that it instantiate then push/pop on it's stack are the om child components


it all works out great because this way the root component query gets constructed proper and it is able to schedule-render and query only the child comps that changed based on their query


wtb pre-baked solution from someone who has a clue what they're doing rather than me bikeshedding 😄


parsing the current route with an om mutate fn is useful imho still to keep track of user's activities on the server but that's about it.. the nav's stack keep track of the scenes (routes) history


@dzannotti TIL wtb and bikeshedding 😛 Have you checked out compassus? I don’t think anyone has applied it to RN, but I think it supports more what you’re thinking I think, wrt multiple roots


It probably won’t work with NavigationExperimental though, so you’d probably have to work on the animations manually.


@dzannotti: how does on-next feel like for you?


@misha great, but still overburdened with too many things (same feeling i share for falcor/graphql)


Are you able to split your app into data and representation layers? Or do you get everything baked into single blob?


Like, are you able to implement all data mutations and shapes, and then write components+routes separately using that data+fns?


not sure what you mean, each component gets the keys requested, in the read fn I have a default case that handles stuff that is already in state, and before that i check for values of known computed keys


the only thing that i wasn't able to do is to create a composition of mutations


Cool, I had an impression, that data layout and mutations will be greatly influenced by ui, even though technically those can live in separate namespaces


(In om-next)


@misha Perhaps i'm using it wrong? I heard tom kay saying that he mostly uses a data tree shaped like he needs in ui, but i don't


I want to use data tree shaped as my backend one is )


That lets me share mutation fns across ios, server, and web. To some degree


i use a normalized db shape for all my data and a bunch of lists that referenciate such data + some computed values