Hello! I've been looking into adding better suppor...
# compose-destinations
d
Hello! I've been looking into adding better support for SavedStateHandle with destinations. Using the following resources https://composedestinations.rafaelcosta.xyz/destination-arguments/navigation-arguments?_highlight=saved#navigation-arguments-class-delegate https://developer.android.com/topic/libraries/architecture/viewmodel/viewmodel-savedstate#savedstate-stateflow I've ended up with something like this as a basic example:
Copy code
class EditNameDialogViewModel(
    ...
    private val handle: SavedStateHandle
) : ViewModel() {

    private val navArgs = EditNameDialogDestination.argsFrom(handle)
    private val inputName = handle.getStateFlow("inputName", navArgs.initialName.value)
    
    val uiState = // build ui state from flows
   
    fun onNameChanged(name: String) {
        handle["inputName"] = name
    }
}
I know there is some solutions like: https://gist.github.com/marcellogalhardo/2a1ec56b7d00ba9af1ec9fd3583d53dc that makes it a bit easier with creating a MutableStateFlow directly, and make it a bit cleaner. How do peeps here do it?
i
Arguments are immutable, so you don't need a flow at all here - flows are for multiple values that change over time
d
Well this would also mean my input get's cleared across process death right?
i
No? What makes you think that
d
Because if they are not part of savedStateHandle?
i
They are though? That's why the argsFrom(handle) works
d
So if the user edits the text, start entering something else. Leaves app and then returns (and app was stopped by system,
adb shell am kill <package>
), If I don't update my savedStateHandle it would be reset to the original value right?
i
Ah, you aren't talking about your arguments, you're talking about a different field entirely that you want backed by SavedStateHandle?
d
Ah, yes. Maybe I wasn't clear enough on this.
i
Ah, okay, sorry yeah that's probably on me - still early here ๐Ÿ˜…
If you're in Compose land, I'd strongly consider using one of the
by handle.saveable
overloads, which make it possible to have rememberSaveable like APIs backed by your SavedStateHandle: https://developer.android.com/reference/kotlin/androidx/lifecycle/SavedStateHandle#(androidx.lifecycle.SavedStateHandle).saveable(androidx.compose.runtime.saveable.Saver,kotlin.Function0)
๐Ÿ‘ 1
Maybe you don't need flows at all, tbh
d
It is a bit of preference, but we go for MVI style pattern, where we generate a single UiState and also do all the validation of input etc in the ViewModel to make the views as dumb as possible, so there I'm not in a Composable context. ๐Ÿ˜•
s
You can still have MutableState inside your VM without having to be inside a composable context. Look into this https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:lifecycl[โ€ฆ]Handle.saveable&ss=androidx%2Fplatform%2Fframeworks%2Fsupport
d
@Stylianos Gakis Thanks for the reply, but this I can't collect as a flow in any way, right? It just backs the property with the savedStateHandle.
I saw this issue, seems like this usecase have been denied before (getting a
MutableStateFlow
directly from savedStateHandle): https://issuetracker.google.com/issues/235574686
s
Yeah that's what Ian said, you may just be able to have it as MutableState, instead of using Flows. But receiving it as a flow is still an option if you want that yeah. It's up to you really.
๐Ÿ‘ 1
๐Ÿค— 1
d
Not having it as a flow would possibly also make me not create a new UiState with the updated input. So I'd prefer knowing that I will produce a new UiState. But thanks for the idea and help.
s
The way that these APIs work where you can get a MutableState out of it and seemingly have a two-way binding with what's in the SSH itself, is that it does not actually save the value back into the SSH every time you change the MutableState value itself. It keeps that change locally, and only when there is a need for the state to be saved, say by process death happening, only then it looks inside the current value, and saves it back to the SSH
d
Makes sense, that lowers the overhead quite a bit.
s
Oh hi btw, I just realized I met you at Kotlinconf ๐Ÿ˜… Fun to see you here too!
๐Ÿค— 1
d
Haha yes! ๐Ÿ˜„ ๐Ÿค— Also smiled a bit when I saw you answered the link above 3 years ago ๐Ÿ˜…
๐Ÿ˜… 1
s
Haha I was surprised to see myself there too, trust me ๐Ÿ˜‚
๐Ÿ˜‚ 1
r
Hey @David, so as guys have said, this is not really related to Compose Destinations, right? It doesnโ€™t make a lot of sense to change the navigation arguments.. they should be the initial value of a flow (which you can separately save with another name on SavedStateHandle). Correct?
๐Ÿ‘ 2
d
@Rafael Costa I was thinking there was possible opening of generating some helper functions that could make savedStateHandle and it's arguments easier to handle but it doesnt seem to be the case. So no, ended up not being of any help to compose destinations.
r
No worries at all! Just making sure on my end! Thank you for bringing it up! ๐Ÿ™‚
โค๏ธ 1