https://kotlinlang.org logo
Title
n

Nikola Milovic

11/30/2021, 10:03 AM
Hello, a decompose question. I have the following config, (screens are components + stores practically) Screen A has two children, Nothing and Child B (screen B). When Nothing is the child, screen A displays its content, when the child is B then it shows screen B. Practically corresponding (since it's a web app) to
url/user/
and
url/user/profile/
I am having issues with going back and navigating to screen A again. If I am on screen B, I cannot press back on my mouse and the browser doesn't give me the back option. Also when navigating from some other screen back to screen A, it still contains Configuration B, because I cannot push a new configuration (getting the unique Config error), so I am using the
pushToFront
. What would be the approach, besides adding a back button on desktop to go about this? (I think that mobile handles the back button normally, would have to test it). Also, I am not really proficient in web dev, would it be possible to have URLs and have them go back option with Decompose and Web?
a

Arkadii Ivanov

11/30/2021, 10:33 AM
Hello. There seems to be multiple questions here.
If I am on screen B, I cannot press back on my mouse and the browser doesn't give me the back option.
This is because the browser is not aware of the back stack in your app. When you navigate, the page does not reload. It still the same page, but with another content. One of the ways to make the browser navigation button to work, is to load URLs and use deep-links approach. This will cause the page to reload, which might be slower. And also there will be always only one current screen created (screens in the back stack will be always in "not created" state). You will need to do this manually. E.g expose a callback from your
Root
component:
navigate: (url: String) -> Boolean = { false }
, and call it in your
Root
. If the returned value is
false
, then use the
Router
for navigation. And also pass
url: Url
to the
Root
constructor, decode it and fill
router(...)
initial arguments properly. There should be a better approach, but I didn't try it yet. Please see the thread: https://kotlinlang.slack.com/archives/C01F2HV7868/p1636278818083400 I need to check how it is implemented in the
routing-compose
library. Perhaps there is a way to just manipulate the browser history and the URL manually, so it will follow the back stack. And hook to the URL change or so. I will really appreciate if you check it yourself and provide feedback here!
Also when navigating from some other screen back to screen A, it still contains Configuration B, because I cannot push a new configuration (getting the unique Config error), so I am using the 
pushToFront
When navigating back you should pop, not
push
. And also what is
pushToFront
?
n

Nikola Milovic

11/30/2021, 10:55 AM
pushToFront
was supposed to be
bringToFront
typo sorry. Okay the routing code seems rather understandable. It seems that there is the regular URL option and the hash url option (that might be preferable). So from my very limited understanding to make this work it would require: 1. Global var router ( thankfully JS supports this ) 2. The router intercepts the browser path (if the user manually types a path, not sure how to do this) and exposes the router to handle the navigation (something like Nextjs useRouter hook) 3. Using things like
window.history.pushState(null, "", goToLocation)
        currentPath.value = window.location.pathname
The history and the url/ current path is managed
a

Arkadii Ivanov

11/30/2021, 10:59 AM
Yeah, something like this. I also have very little experience with web. But maybe you can avoid "global" things. Perhaps you can setup everything in
main
function, where you create
root
. Also I remember that
pushState
causes page reload, but I might be wrong.
n

Nikola Milovic

11/30/2021, 10:59 AM
What
pushState
exactly?
a

Arkadii Ivanov

11/30/2021, 11:00 AM
window.history.pushState
n

Nikola Milovic

11/30/2021, 11:12 AM
4. Now in terms of decompose, things get a bit unclear for me, for example I am currently handling it like so
IndexPage
val routerState = props.component.routerState.subscribeAsState()
val child: Child = routerState.activeChild.instance

    when (child) {
            is Child.PageA -> PageA { attrs { this.component = child.component } }
            is Child.PageB -> PageB { attrs { this.component = child.component } }
        }
Which works perfectly well for web, mobile and other platforms. So a browser only/ Js only solution would be preferable so that the other platforms can remain somewhat the same.
window.history.pushState
doesn't refresh from what I've read, so it would serve the usecase.
Hmm, I am a bit lost now as the Configurations are needed for data, so maybe the router would parse the URL and create the correct configuration. Also dynamic urls like
/user/[id]/profile
would be a problem
a

Arkadii Ivanov

11/30/2021, 11:18 AM
What you mean by "Configurations are needed for data"? What is the issue?
n

Nikola Milovic

11/30/2021, 11:21 AM
Thinking about it more, it seems pretty doable with the Router for JS that has mapped paths to proper Configuration/ Components. Also dynamic paths would work if you map
users/[id]
to ProfileConfiguration for example so that
users/123id
would create ProfileConfiguration with parameter Id being 123id. the thing that confuses me is nested routes but that is due to my unfamiliarity with decompose internals
Configurations are needed for data
I was just refering to how data is passed from parent to child, eg how path
users
would pass data to
users/profile
in the browser
a

Arkadii Ivanov

11/30/2021, 11:23 AM
So this is the deep-linking question. You can pass a URL to Root, where it will decode its level's configurations. The inner URL parts can be delegated to nested components, and decoded the same way.
You can also supply initialBackStack argument to router, so there will be history to go back.
n

Nikola Milovic

12/05/2021, 10:03 AM
@Arkadii Ivanov will you be raising an issue for this perhaps? Is it a functionality that might see the light of day in the future?
a

Arkadii Ivanov

12/05/2021, 10:10 AM
Sorry I don't get, what would you like to be done in the scope of the issue?
n

Nikola Milovic

12/05/2021, 11:59 AM
@Arkadii Ivanov Oh sorry for not clarifying was wondering if this kind of web browser routing would maybe fit into the Decompose library/ Extension Library in the future
a

Arkadii Ivanov

12/05/2021, 12:03 PM
I think it would be good to have an issue to investigate options at least. Do you mind creating one?
👌 1