One thing that's confusing me a little bit about d...
# compose-android
b
One thing that's confusing me a little bit about dedicated stateHolder classes, is this value in the NiaAppState in the Now In Android Sample Project.
Copy code
val topLevelDestinationsWithUnreadResources: StateFlow<Set<TopLevelDestination>> =
    userNewsResourceRepository.observeAllForFollowedTopics()
        .combine(userNewsResourceRepository.observeAllBookmarked()) { forYouNewsResources, bookmarkedNewsResources ->
            setOfNotNull(
                FOR_YOU.takeIf { forYouNewsResources.any { !it.hasBeenViewed } },
                BOOKMARKS.takeIf { bookmarkedNewsResources.any { !it.hasBeenViewed } },
            )
        }.stateIn(
            coroutineScope,
            SharingStarted.WhileSubscribed(5_000),
            initialValue = emptySet(),
        )
This value is only used in one spot, inside of NiaApp.kt to pass into the BottomBar to determine whether a UI element in the bottom bar should have a badge indicating if there's unread resources or not. I feel like normally this is something I'd put in a viewModel perhaps, but in our own project we've heavily followed the pattern of having a stateHolder at least for our main App composable. Another question I have then, is grabbing a user from the UserRepository a good idea to do in the stateHolder? I need to have the user and pass it into my ModalDrawerSheet which I'm using for a side navigation hamburger menu. I can't tell the difference between something like fetching a user to display the data in a drawer, versus grabbing topics that aren't viewed and deciding whether to show a badge or not. To me it seems like the same type of thing, but I'm still not confident on why this block of code from now in android is even in the NiaAppState.kt
f
Using a state holder or a viewmodel can be a bit of a grey area, there is no right or wrong. In my personal opinion, I use state holders for data and logic that is solely related to composables and where the viewmodel does not need to be involved. For instance, if I have a screen with an input field where I want to do some validation (maybe to check it's a valid email address), I would do that in a state holder. If the viewmodel needs to know the value of the field I can use a
snapshotFlow
and push that to the viewmodel as the field is updated, but the validation will remain in the state holder. At the other end, when I need to access the data layer, or do more complex logic, then I would do that in the viewmodel instead of a state holder. Then there is the in-between, where you are accessing some resource (like a network monitor), where you could do either a state holder or a viewmodel, and both would be perfectly fine.
b
would you say in this Nia example it's like a network monitor?
f
No, accessing a repository is something I would have done in the viewmodel
b
@Francesc I see, so it seems like they just decided to do it in the StateHolder in the sample for some reason, perhaps because it was their only usage of accessing a repository and they didn't want to make a ViewModel?
f
possibly, but as I mentioned earlier, this is subjective