Fork me on GitHub
#cljsrn
<
2016-10-25
>
dzannotti11:10:58

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

savelichalex14:10:08

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

dzannotti14:10:16

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

dzannotti14:10:40

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

savelichalex14:10:01

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

savelichalex14:10:48

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

savelichalex14:10:38

@dzannotti and as I know, NavigatorExperimental is steel unstable

dzannotti14:10:58

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

dzannotti14:10:08

how do you set the query for the current view?

savelichalex14:10:34

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

dzannotti14:10:47

the om.next component query

dzannotti14:10:17

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

levitanong14:10:39

@dzannotti I’ve been using NavigatorExperimental with my RN om.next app. See: https://github.com/vikeri/re-navigate It uses reagent, but the principles are the same. Just implement the mutations on the navigation stack. see https://github.com/vikeri/re-navigate/blob/master/src/navigator_cljs/handlers.cljs#L40 onwards

dzannotti14:10:45

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

sineer15:10:22

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

dzannotti15:10:57

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

dzannotti15:10:57

the root component for the reconciler is the router

sineer15:10:26

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

dzannotti15:10:51

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

dzannotti15:10:17

(aka read-understand-copy :D)

sineer15:10:56

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

sineer15:10:53

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 🙂

tiensonqin15:10:56

Hi, @dzannotti @sineer I'm using re-frame and ex-navigation on exponent, https://github.com/tiensonqin/lymchat-exp/blob/master/src/lymchat/handlers.cljs#L1116-L1146

tiensonqin15:10:05

Also, if you are interested in lymchat, I made an template(support both om next and re-frame): https://github.com/tiensonqin/exponent-cljs-template

sineer15:10:20

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

tiensonqin15:10:26

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

sineer15:10:53

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

dzannotti15:10:25

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

dzannotti15:10:41

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

dzannotti15:10:02

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

tiensonqin15:10:02

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

dzannotti15:10:38

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

sineer15:10:32

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

sineer15:10:28

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

dzannotti15:10:27

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

sineer16:10:47

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

sineer16:10:47

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

artemyarulin16:10:47

@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

sineer16:10:31

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

artemyarulin16:10:05

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

sineer16:10:10

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

sineer16:10:42

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

sineer16:10:03

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

sineer16:10:27

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.

misha16:10:43

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

artemyarulin16:10:52

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

artemyarulin16:10:51

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

misha16:10:00

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

misha16:10:07

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

misha16:10:25

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

misha16:10:47

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

misha16:10:03

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

misha17:10:12

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

artemyarulin17:10:39

didn’t understand a thing but sounds cool 🙂

levitanong18:10:40

@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:
{scene: 
  {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.

dzannotti18:10:31

No worries, i'm in no rush

dzannotti18:10:13

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

levitanong18:10:55

just include the navigation state in your query 🙂

levitanong18:10:32

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

levitanong18:10:16

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}})
    :app/nav])

dzannotti18:10:15

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

dzannotti18:10:26

so if the view changes, the root query itself changes

dzannotti18:10:40

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

dzannotti18:10:45

am i understanding it wrong?

levitanong18:10:29

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

levitanong18:10:37

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

levitanong18:10:21

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

dzannotti18:10:54

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]

dzannotti18:10:08

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

dzannotti18:10:23

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

levitanong18:10:47

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]

levitanong18:10:07

along with :app/nav

dzannotti19:10:07

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?

levitanong19:10:23

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

dzannotti19:10:27

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)

sineer19:10:23

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

sineer19:10:37

I mean route are om components

sineer19:10:08

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

sineer19:10:37

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

sineer19:10:18

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

dzannotti19:10:45

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

sineer19:10:03

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 😉

sineer19:10:49

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

sineer19:10:27

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

dzannotti19:10:31

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

sineer19:10:37

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

levitanong19:10:06

@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

levitanong19:10:05

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

misha19:10:19

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

dzannotti19:10:21

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

misha19:10:11

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

misha19:10:13

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

dzannotti19:10:18

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

dzannotti19:10:26

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

misha19:10:16

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

misha19:10:41

(In om-next)

dzannotti19:10:30

@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

misha19:10:34

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

misha19:10:23

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

dzannotti19:10:34

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