Home > OS >  Jetpack compose api call with viewModel in infinite loop
Jetpack compose api call with viewModel in infinite loop

Time:01-31

i'am trying to build an app with jetpack compose but when it's come to api call with view model i get an infinite loop. the app keep calling the api and i don't get why. here is my viewmodel :

class LibraryViewModel() : ViewModel() {

var library: ArrayList<PKIssue> = arrayListOf()
var loadLibrary by mutableStateOf(false)


init {
    getLibrary()
}


fun getLibrary(){
    viewModelScope.launch {
        Press.issues(
            result = object : result<ArrayList<Issue>, Error> {
                override fun succeed(result: ArrayList<Issue>?) {
                    loadLibrary = true
                    if (result != null) {
                        library = result
                    }
                  
                }

                override fun failed(error: Error?) {
                    loadLibrary = false
                }
            })
    }
}

But as soon as i init my viewModel i get infinite call to my api, here is how i try to declare it :

@SuppressLint("StateFlowValueCalledInComposition")
@Destination
@Composable
fun HomeScreen(
    navigator: DestinationsNavigator,
   libraryViewModel: LibraryViewModel = LibraryViewModel()
) {

or inside the composable : val libraryViewModel = LibraryViewModel() but i get the same problem, i am i missing something ? it seem that it wait the end of the api call to put loadLibrary at true but in the mean time it keep call getLibrary() in loop. Thanks for helping

CodePudding user response:

When you use

libraryViewModel: LibraryViewModel = LibraryViewModel()

You are directly constructing a brand new instance of your LibraryViewModel every time that method recomposes. Since you probably read your loadLibrary value once getLibrary returns, that causes a recomposition of that method, hence the infinite loop (as the recomposition again causes another brand new instance to be created...which kicks off a load...which causes another recomposition).

Instead, you should be following the documentation on using ViewModels with Compose:

  1. Add the androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1 dependency to your build.gradle file

  2. Use the viewModel() method to instantiate your ViewModel.

fun HomeScreen(
    navigator: DestinationsNavigator,
   libraryViewModel: LibraryViewModel = viewModel()
) {

The viewModel() method is what actually causes your ViewModel to be cached and stored across recompositions, navigating to a different screen, and across configuration changes. Since by using that method you'll only have a single instance of that ViewModel, you won't run into the same infinite loop.

  • Related