Bharat Kumar
Bharat Kumar

Reputation: 956

conditional navigation in compose, without click

I am working on a compose screen, where on application open, i redirect user to profile page. And if profile is complete, then redirect to user list page.

my code is like below

@Composable
fun UserProfile(navigateToProviderList: () -> Unit) {

val viewModel: MainActivityViewModel = viewModel()

if(viewModel.userProfileComplete == true) {
    navigateToProviderList()
    return
}

else {
  //compose elements here
}

}

but the app is blinking and when logged, i can see its calling the above redirect condition again and again. when going through doc, its mentioned that we should navigate only through callbacks. How do i handle this condition here? i don't have onCLick condition here.

Upvotes: 9

Views: 2333

Answers (2)

Amin Keshavarzian
Amin Keshavarzian

Reputation: 3963

The LaunchedEffect did not work for me since I wanted to use it in UI thread but it wasn't for some reason :/ However, I made this for my self:

@Composable
fun <T> SelfDestructEvent(liveData: LiveData<T>, onEvent: (argument: T) -> Unit) {
    val previousState = remember { mutableStateOf(false) }
    val state by liveData.observeAsState(null)
    if (state != null && !previousState.value) {
        previousState.value = true
        onEvent.invoke(state!!)
    }
}

and you use it like this in any other composables:

SingleEvent(viewModel.someLiveData) {
        //your action with that data, whenever it was triggered, but only once
}

Upvotes: 1

Phil Dukhov
Phil Dukhov

Reputation: 88457

Content of composable function can be called many times.

If you need to do some action inside composable, you need to use side effects

In this case LaunchedEffect should work:

LaunchedEffect(viewModel.userProfileComplete == true) {
    if(viewModel.userProfileComplete == true) {
        navigateToProviderList()
    }
}

In the key(first argument of LaunchedEffect) you need to specify some key. Each time this key changes since the last recomposition, the inner code will be called. You may put Unit there, in this case it'll only be called once, when the view appears at the first place

Upvotes: 10

Related Questions