Thread
#compose
    Tony Kazanjian

    Tony Kazanjian

    1 year ago
    Hi all! I'm new to Compose and was wondering how the typical ViewModel approach (i.e. one fragment/activity -> one ViewModel) applies to Compose. If my entire app is a single activity that navigates through composables, and each composable would have different data for it's state that is fetched via a coroutine in a ViewModel, would I then inject every single VM I'd need for the whole app inside the Activity? That doesn't seem right.
    i

    Ian Lake

    1 year ago
    If you are using Navigation Compose (https://developer.android.com/jetpack/compose/navigation), then ViewModels created within one composable screen will automatically be scoped to just that screen
    Tony Kazanjian

    Tony Kazanjian

    1 year ago
    Thanks Ian, but I think that example leads to something where we just have a single viewmodel in an Activity that is used as a parameter to the Composable. It just looks to me now that I don't need multiple viewmodels in a single-Activity architecture since I'm no longer using Fragments. Therefore, MainViewModel would be the single access point to launch each and every UseCase I'd need
    Yeah I know that sounds terrible 😓 , but I just haven't seen an example of how we're meant to work with different ViewModels within an activity that switches Composables for it's screens
    i

    Ian Lake

    1 year ago
    I'm not sure I follow. Compose just lets you do
    val yourViewModel: YourViewModel = viewModel()
    as per the docs: https://developer.android.com/jetpack/compose/interop#viewmodel
    And that automatically gets scoped to that single screen if you're using it within Navigation Compose's
    NavHost
    Tony Kazanjian

    Tony Kazanjian

    1 year ago
    Got it! Thanks for pointing me to the interop section of the docs, that's exactly what I needed to see
    i

    Ian Lake

    1 year ago
    Also note that activities, fragments, compose, and everywhere else has always supported multiple ViewModels - there's never been a 1:1 requirement
    Tony Kazanjian

    Tony Kazanjian

    1 year ago
    Of course, that's generally just the pattern I've stuck to, unless there is a need for a shared VM.
    Robert Menke

    Robert Menke

    1 year ago
    Is the challenge you’re facing dealing with in-memory state that should live beyond the lifetime of a composable? For example, if I wanted to fetch a profile avatar when my app loads so that it’s always available when I go to my profile tab I may want that Bitmap loaded into memory for the entire lifetime of my application (or at least the URL that I can use to load it). 3 options here as far as I can tell:1. Use a storage mechanism like Room for anything that needs to persist beyond a composable 2. Use something like hilt to scope your viewmodels 3. Create all the instances you need in your activity and pass them in to your composables in the function call
    i

    Ian Lake

    1 year ago
    Keep in mind that any image loading library such as Coil, Picasso, Glide, etc. already have an in memory cache
    b

    Bradleycorn

    1 year ago
    @Ian Lake if I understand the current state of affairs, if your ViewModel has any dependencies, you have to roll your own Factory in order to use the compose
    viewModel()
    extension, right?
    val vm: MyViewModel = viewModel(factory = MyViewModelFactory)
    And if you are using Hilt for DI, then … ??
    i

    Ian Lake

    1 year ago
    Looks like there's a workaround for Hilt's issue on their tracking bug (since the issue is with what Hilt is doing): https://github.com/google/dagger/issues/2166#issuecomment-723775543
    Tony Kazanjian

    Tony Kazanjian

    1 year ago
    FWIW, I have been using Koin. Incredibly simple. If I implement each ViewModel as a KoinComponent, I can inject my dependencies into the viewmodel and instantiate the viewmodel in the Composable. https://doc.insert-koin.io/#/koin-core/koin-component