androidkotlinandroid-jetpack-composeviewmodelandroid-viewmodel

Cannot create an instance of com.example.project.mainViewModel when using Jetpack Compose


"Hello everyone, I am trying to build an Android application using Jetpack Compose. However, when I try to run the app, an error appears like this:

Process: com.example.bangkit_recycleview, PID: 7393 java.lang.RuntimeException: Cannot create an instance of class com.example.pokedex.MainViewModel

I am not using hilt, I just want to use jetpack compose only but I am facing an error like that when I am not using hilt, I put the detail of my code so you can see it more clearly

here is my code:

//MainActivityScreen

@Composable
fun MainActivityScreen(viewModel: MainViewModel = viewModel()) {
    val context = LocalContext.current
    val coroutineScope = rememberCoroutineScope()

    val foods = viewModel.foods

    LaunchedEffect(key1 = context) {
        viewModel.getAllFoods()
    }
}

//MainViewModel



class MainViewModel(private val foodDao: FoodDao) : ViewModel() {
    private var _foods: List<FoodEntity> = emptyList()

    val foods: List<FoodEntity>
        get() = _foods

    fun getAllFoods() {
        viewModelScope.launch {
            _foods = withContext(Dispatchers.IO) {
                foodDao.getAllFoods()
            }
        }
    }

    fun insertFood(newFood: FoodEntity) {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                foodDao.insert(newFood)
            }
        }
    }
}

Can anyone help me to find the solution of this problem?


Solution

  • Since you're not using Hilt for dependency injection, you need to provide an instance of FoodDao to your MainViewModel manually.

    you can modify your code to provide the FoodDao dependency to MainViewModel:

    @Composable
    fun MainActivityScreen(viewModel: MainViewModel = viewModel()) {
      val context = LocalContext.current
      val coroutineScope = rememberCoroutineScope()
    
      val foodDao = remember { AppDatabase.getInstance(context).foodDao()}
      val viewModel = remember { MainViewModel(foodDao)}
    
      val foods = viewModel.foods
    
      LaunchedEffect(key1 = context) {
        viewModel.getAllFoods()
     }
    }
    

    In this modification, we create an instance of FoodDao using the AppDatabase (assuming AppDatabase is your Room database class) and pass it to the MainViewModel constructor. This way, the MainViewModel has access to the required dependencies.