Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call api again when backStack to the jetpack compose screen

I call an API in the view model init. When I navigate to another screen and back to the previous screen I want to call API again clientInfoOnEvent() to update data, but I can do it in the Jetpack Compose. how can I do it?

Viewwmodel codes:

@HiltViewModel
class ProfileViewModel @Inject constructor(
    private val profileUseCases: ProfileUseCases,
    private val clientNavigator: ClientNavigator,
    private val isLoggedInDataStore: IsLoggedInDataStore
) :
    ViewModel(), ClientNavigator by clientNavigator {

    private val _state = mutableStateOf(ProfileState())
    val state: State<ProfileState> = _state

    init {
        clientInfoOnEvent()
    }

    fun clientInfoOnEvent() {
        profileUseCases.getClientInfoUseCase().onEach { result ->
            when (result) {
                is Resource.Success -> {
                    _state.value = state.value.copy(info = result.data)
                }
                is Resource.Error -> {
                    _state.value =
                        state.value.copy(error = result.message ?: "An unexpected error occurred")
                }
                is Resource.Loading -> {
                    _state.value = state.value.copy(isLoading = true)
                }
            }
        }.launchIn(viewModelScope)
    }

}

Screen codes:

val state = viewModel.state.value

Column(
    modifier = modifier.fillMaxWidth(),
    verticalArrangement = Arrangement.Center,
    horizontalAlignment = Alignment.Start
) {
    state.info?.apply {
        Text(
            text = "$givenName $lastName",
            style = AppFont.PoppinsTypography.button,
            color = AppColor.neutralColor.CHARCOAL,
            modifier = modifier.padding(top = 4.dp, bottom = 4.dp)
        )
        val clientData = let {
            it.copy(currency = Currency().copy(signSvg = it.currency?.signSvg.urlEncoder()))
        }
        TextIcon(
            text = stringResource(R.string.edit_profile),
            icon = painterResource(id = R.drawable.ic_right),
            color = AppColor.neutralColor.SPANISH_GRAY,
            style = AppFont.PoppinsTypography.caption,
            onCLick = {
                state.info?.let {
                    viewModel.navigate(
                        EditProfileDestination.createEditProfileRoute(
                            Gson().toJson(
                                clientData
                            )
                        )
                    )
                }
            })
    }
} 
like image 960
Saeed Noshadi Avatar asked Mar 18 '26 04:03

Saeed Noshadi


1 Answers

You can use LaunchedEffect: it'll make a call once when the view appears.

val state = viewModel.state.value
LaunchedEffect(Unit) {
    viewModel.clientInfoOnEvent()
}

You can remove this call from init to prevent double call in the first appearance. Check out more about side effects in Compose in documentation.

like image 140
Philip Dukhov Avatar answered Mar 20 '26 19:03

Philip Dukhov