View Model Creation in Jetpack Compose
Tags: android, kotlin, beginners, jetpackcompose
Published: 2022-10-21 23:50:58

**2 ways (by viewModels and viewModel() composable function) to create view model in your Jetpack compose app**

In Jetpack Compose, you can use either [by viewModels](https://vtsen.hashnode.dev/recommended-ways-to-create-viewmodel-or-androidviewmodel#heading-by-viewmodels-activityviewmodels) or `viewModel()` composable function to create view model.

## by viewModels

 ```kotlin
class MainActivity : ComponentActivity() {

    private val viewModel by viewModels<MainViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            MainScreen(viewModel)
        }
    }
}
```
can be just replaced with 

## viewModel() composable

```kotlin
class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            MainScreen(viewModel())
        }
    }
}
```
*Source code example (Simple Rest API Demo App): [MainActivity.kt](https://github.com/vinchamp77/Demo_SimpleRestAPI/blob/master/app/src/main/java/vtsen/hashnode/dev/simplerestapidemo/ui/MainActivity.kt).* 

> If that doesn't work, you want to explicity include this library in your `build.gradle` file.
```
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.4.0'
```

## by ViewModels (custom constructor)
For view model creation that has custom constructor, `by viewModels` code looks like this:

```kotlin
private val viewModel by viewModels<MainViewModel> {
    MainViewModelFactory(repository)
}
```

## viewModel() composable (custom constructor)
To convert it to `viewModel()` composable function, it looks like this
```kotlin
viewModel(factory = MainViewModelFactory(repository))
```
You pass in the custom view model factory (i.e. `MainViewModelFactory`) as parameter of `viewModel()` composable function.

> Note: `viewModel()` is a composable function, you need to call it within a composable function.

*Source code example (Android News app): [MainActivity.kt](https://github.com/vinchamp77/AndroidNews/blob/master/app/src/main/java/vtsen/hashnode/dev/androidnews/ui/MainActivity.kt).*

## HiltViewModel() - DI Framework
Another way to create view model is to use Hilt dependency injection(DI) framework. It is very similar to `viewModel()` composable function. You just replace it with `hiltViewModel()` which is also a composable function.

```
@AndroidEntryPoint
class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MainScreen(
                viewModel = hiltViewModel(), 
                useSystemUIController = true
            )
        }
    }
}
```
*Source code example (Android News app - Hilt branch): [MainActivity.kt](https://github.com/vinchamp77/AndroidNews/blob/hilt/app/src/main/java/vtsen/hashnode/dev/androidnews/ui/MainActivity.kt).*

For how to use the Hilt dependency injection, refer to this article:
- [Convert View Model to Use Hilt Dependency Injection](https://vtsen.hashnode.dev/convert-view-model-to-use-hilt-dependency-injection)

## Conclusion
I wasn't aware of this `viewModel()` composable function. So I had been using `by viewModel`. I think it is better to use `viewModel()` composable function if your app is Jetpack Compose. You can also call `viewModel()` many times and only one instance of view model is created.

One thing to keep in mind when using `viewModel()` composable function is the **view model lifecycle is scoped to composable function that is still in the back stack**.  If the composable function is removed from the back state, the view model is destroyed. For details, refer to this article.
- [Activity and View Model Lifecycles Demo App](https://vtsen.hashnode.dev/activity-and-view-model-lifecycles-demo-app)

---

*Originally published at [https://vtsen.hashnode.dev](https://vtsen.hashnode.dev/view-model-creation-in-jetpack-compose)*.