https://kotlinlang.org logo
Title
r

rsktash

01/24/2021, 11:20 AM
Hi @Arkadii Ivanov. I’ve asked many many many questions regarding implementation of decompose library. I’m using jetbrains compose, decompose, mvikotlin, ktor, Now I’m trying to navigate to first screen when api throws authentication error. How can I pass router to api service?
a

Arkadii Ivanov

01/24/2021, 11:29 AM
Hi!
How can I pass router to api service?
There is not enough context to answer precisely, but you can pass Router via constructor of the
api service
. Just as normal object. But it may result in coupling. Maybe you can listen for api errors in the root/parant component (owner of the Router)? The
Router
has method
Router.navigate
. You can supply any stack you want. E.g.
Router.navigate { listOf(Configuration.Login} }
, will destroy the current stack and navigate to the Login screen. If the Login screen is already in the back stack, it will be resumed. If not, it will be created.
r

rsktash

01/24/2021, 11:31 AM
What about adding goToLogin fun to RootCompoent and pass RootCompoent to apiService?
a

Arkadii Ivanov

01/24/2021, 11:32 AM
This can also work. If you are fine with the fact, that ApiService will depend on the RootComponent.
r

rsktash

01/24/2021, 11:34 AM
https://github.com/arkivanov/Decompose#why-decompose I read the docs and you have stated that components won’t be destroyed . So we could pass it as a weak reference ?
a

Arkadii Ivanov

01/24/2021, 11:38 AM
They are not destroyed while in the back stack. But once removed, they are destroyed. Just like Android Fragments.
Probably I need to elaborate this point in the docs
r

rsktash

01/24/2021, 11:39 AM
Yes but root component will stay there while app is running isn’t it?
a

Arkadii Ivanov

01/24/2021, 11:42 AM
Yes it will stay
r

rsktash

01/24/2021, 11:52 AM
I’ve a repo for every component which encapsulate base ApiService. I’ll create AppComponentContext which extends ComponentContext with an extra ErrorHandler class which receives RootCompont. With this error handler I can handle authentication errors in every repo class
a

Arkadii Ivanov

01/24/2021, 12:44 PM
This is the second time I'm asked about
ComponentContext
extension. Decompose is quite flexible, so I came up with a solution. Would be nice if you try and provide your feedback in the issue.
Updated the previous message with the correct link.
r

rsktash

01/24/2021, 1:56 PM
Here error handling middleware class
a

Arkadii Ivanov

01/24/2021, 2:01 PM
Yep, looks valid.
Btw MVIKotlin, Reaktive and Decompose - full house of the libs I'm maintaining!
r

rsktash

01/24/2021, 2:04 PM
As the middleware will be available from everywhere via AppComponentContext we can bind error messages to Store state then to model
a

Arkadii Ivanov

01/24/2021, 2:08 PM
Yes. There is just one downside, you will need to use the middleware every time. As an option, you could try to encapsulate this logic into your networking layer, and broadcast errors from there. So you could subscribe to errors in the Root component and navigate accordingly.
r

rsktash

01/24/2021, 2:09 PM
But there may be errors only child component is aware of processing logic
a

Arkadii Ivanov

01/24/2021, 2:11 PM
That's makes sense. Then your solution should work.
r

rsktash

01/24/2021, 2:12 PM
Or we can implement as BackPressedDispatcher?
Maybe error handling mechanism will be decompose build-in component?
a

Arkadii Ivanov

01/24/2021, 2:15 PM
BackPressedDispatcher is like a relay. You can listen for events, and send Back events to it. Router is also a subscriber. It navigates one by one. But you might need to replace all current stack with just one Login screen. Better to not mess with the BackPressedDispatcher and just call Router manually.
At the moment I don't want add such a logic. It can be easily done client-side, and every use case is different.
r

rsktash

01/24/2021, 2:18 PM
I mean If we have component tree like this: RootComponent -> DashboardComponent -> ListComponent every child component can dispatch error handle or pass to upper level
a

Arkadii Ivanov

01/24/2021, 2:20 PM
You can extend ComponentContext with your own error handler. Or just pass it via constructor to all children. It's up to you.
r

rsktash

01/25/2021, 1:47 PM
Hey. How can I handle appbar navback button press by default? I couldn’t find sample code How can I access backpress handler ?
a

Arkadii Ivanov

01/25/2021, 1:49 PM
Is appbar is part of the child or parent?
r

rsktash

01/25/2021, 1:50 PM
Every screen has it’s appbar
a

Arkadii Ivanov

01/25/2021, 1:56 PM
In this case here is an example.
Details
responsibility ends once Back button is clicked in the appbar. It is Root's responsibility to navigate back.
r

rsktash

01/25/2021, 1:59 PM
I know it. I’m asking about the default handler. When I set handleBackButton = true and click system back navigation it automatically pops back. But how can I access this handler and bind to my appbar navbutton?
a

Arkadii Ivanov

01/25/2021, 2:08 PM
Looks like you are trying to use the
BackPressedDispatcher
in your child component. Normally children should not be aware of the navigation logic. Navigation logic should be Parent's responsibility. Children should only tell Parents when they are finished, so the Parent can decide what to do (e.g. execute
Router.pop()
). But if you really want, you can call
backPressedDispatcher.onBackPressed()
in a Component.
r

rsktash

01/25/2021, 2:11 PM
Yes I’m trying to implement default back press handler because not every component needs custom handler for this event. Thank you. Now I’ll try
If I pass the handler to @composable functions via ambients and use it as default onclick handler is it ok?
a

Arkadii Ivanov

01/25/2021, 2:16 PM
It will work. However it is better to use Components's BackPressedDispatcher instead. At the moment they are same instances every time, but this might change in future, so each child will have its own instance. Your Composable function can talk to its component (e.g. call a method).
r

rsktash

01/25/2021, 2:24 PM
Thank you. How can we implement same logic for both backpress and navback click events? For example: We have a screen where some data will be changed and when user tries to go back it must show dialog
a

Arkadii Ivanov

01/25/2021, 2:28 PM
In this case I believe this logic should be in the Child component. It can hook to the
BackPressedDispatcher
and to the AppBar Back button. In both cases it should show a dialog and once confirmed, the Child component could emit an
Output.Finished
(or just call a callback passed via constructor, whatever you prefer).
The Dialog should part of the Child's state, obviously.
Depending on your requirements, you may want to show the dialog in the Parent. In this case children should tell the Parent that the AppBar's back button is clicked. And then the reset will be handled by the Parent. The Parent should hook to the
BackPressedDispatcher
in this case.
r

rsktash

01/25/2021, 2:42 PM
Thank you can you tell me the proper way to hook to backpressdispatcher in component?
a

Arkadii Ivanov

01/25/2021, 2:46 PM
Yes, you should use
register
method. And don't forget to unregister at the end of lifecycle. You should return
true
in
onBackPressed
method, so the back navigation is blocked at this point.
r

rsktash

01/25/2021, 2:47 PM
Or smth like this
a

Arkadii Ivanov

01/25/2021, 2:47 PM
Yes, the last example is correct
Maybe better to register in onCreate
r

rsktash

01/25/2021, 2:56 PM
You mean ?
lifecycle.doOnCreate {  }
a

Arkadii Ivanov

01/25/2021, 2:56 PM
Yep. Or
lifecycle.subscribe(onCreate=, onDestroy=)
r

rsktash

01/25/2021, 2:57 PM
Then what about binding labels. In the sample app it was bound in init block
a

Arkadii Ivanov

01/25/2021, 2:58 PM
They are normally bound using
binder
, which handles the lifecycle
r

rsktash

01/26/2021, 8:23 AM
Hi @Arkadii Ivanov how can we change appBar if we implement single appBar for the app? Now I’m thinking about changing content depending on screen size. For example when app opened in a phone device ui flow will be root -> list -> item view and when app opened in a tablet ui flow will be root -> list & item combined
a

Arkadii Ivanov

01/26/2021, 10:08 AM
Hi. You take some examples from here: https://github.com/arkivanov/Decompose/discussions/47