Code Monkey home page Code Monkey logo

Comments (7)

raamcosta avatar raamcosta commented on May 13, 2024 1

Hi @5AbhishekSaxena ! 👋

So you have some options, I'll try to go over them.

  1. You can just use a default value for the ViewModel:
@Composable
@Destination(start = true)
fun SampleScreen(
    viewModel: SampleViewModel = hiltViewModel(),
    navigator: DestinationsNavigator,
) {
         // components
}
  1. You can manually call that screen:
@Composable
fun NavigationComponent(
    modifier: Modifier = Modifier
) {

    DestinationsNavHost(
        navGraph = NavGraphs.root,
        modifier = modifier
    ) {
        composable(SampleScreenDestination) {
            SampleScreen(
                viewModel = hiltViewModel(),
                navigator = destinationsNavigator
            )
        }
    }
}

Btw number 2 can be used to pass anything that you may want to pass from the NavHost down (like lets say the ScaffoldState.
AAAND you still don't need to call all your screens manually, you can opt to just manually call the screens you need to pass something explicitly. More info here.
BUT I usually go with 1 for the ViewModel, coz it can be built anywhere, it doesn't need to be constructed at the NavHost level.

Glad you opened this because it reminds me.. I should add a compile time error if you define some parameter that the lib cannot provide 🤔
I'll add that to my todo list.

Let me know if the solutions seem good to you!

from compose-destinations.

raamcosta avatar raamcosta commented on May 13, 2024 1

Ahh the compile-time error won't work because people can just be manually calling them. I can improve the error message though :)

from compose-destinations.

raamcosta avatar raamcosta commented on May 13, 2024 1

Not at all! I'd be thrilled if you could! 🙂
I honestly haven't had the time to refine the documentation to what it should be 😔

Btw if people are not using Hilt, your solution might not be enough if you plan to access the navigation arguments from the SavedStateHandle. For that you need something like this:

    class Factory(
        navBackStackEntry: NavBackStackEntry
    ) : AbstractSavedStateViewModelFactory(
        owner = navBackStackEntry,
        defaultArgs = navBackStackEntry.arguments
    ) {

        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel?> create(
            key: String,
            modelClass: Class<T>,
            handle: SavedStateHandle
        ): T {
            return ProfileViewModel(handle) as T
        }
    }
    
    // And to get the VM:
    //...
    val vm = viewModel<ProfileViewModel>(
        factory = ProfileViewModel.Factory(navBackStackEntry)
    )

from compose-destinations.

5AbhishekSaxena avatar 5AbhishekSaxena commented on May 13, 2024 1

Cool, I'll create a PR with the suggestions for the documentation.

Btw if people are not using Hilt, your solution might not be enough if you plan to access the navigation arguments from the SavedStateHandle.

A really good solution, thanks. I'll update the same in my project.

from compose-destinations.

raamcosta avatar raamcosta commented on May 13, 2024 1

I'll close the issue then, feel free to reopen it or add more comments if you want to :)

from compose-destinations.

5AbhishekSaxena avatar 5AbhishekSaxena commented on May 13, 2024

Thanks for the quick reply,

I went with method #2 to avoid the default value thingy.

If somebody isn't using hilt, they can refer to this

@Composable
@Suppress("UNCHECKED_CAST")
private fun getSampleScreenViewModel(): SamplelScreenViewModel {
    return viewModel(factory = object : ViewModelProvider.Factory {
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            return SampleScreenViewModel() as T
        }
    })
}

and used it like this

@Composable
fun SampleNavigationComponent(
    modifier: Modifier = Modifier
) {

    DestinationsNavHost(
        navGraph = NavGraphs.root,
        modifier = modifier
    ) {
        composable(SampleScreenDestination) {
            SampleScreen(
                viewModel = getSampleScreenViewModel(),
                navigator = destinationsNavigator
            )
        }
    }
}

Also, I found the documentation a bit confusing or missing details, would you mind if I suggest the changes?

from compose-destinations.

5AbhishekSaxena avatar 5AbhishekSaxena commented on May 13, 2024

Ahh the compile-time error won't work because people can just be manually calling them. I can improve the error message though :)

An IDE warning should work just fine.

from compose-destinations.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.