Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for ViewModels should not expose suspending functions
Subbu Lakshmanan
Subbu Lakshmanan

Posted on

ViewModels should not expose suspending functions

Why

Sometimes the developer may add asuspend keyword to a function that calls another suspending function as that's the first auto-suggestion/warning provided by the IDE.

IDE warning

IDE makes it easy for the developer to auto-fix the warning by adding thesuspend keyword to the function.

IDE auto-suggestion

But, this breaks the ruleClasses extending "ViewModel" should not expose suspending functions.

Views should not be responsible for directly triggering coroutines. Hence, ViewModel classes should prefer creating coroutines instead of exposing suspending functions to perform some piece of business logic. This approach allows for easier testing of your application, as ViewModel classes can be unit tested, whereas views require instrumentation tests.

What to do

When you find a function in a ViewModel which breaks this rule, follow these steps to refactor it:

  1. Find the need for thesuspend keyword in the function, i.e., check if the function is calling any other suspending function
    • e.g.,listOfPlants.collectLatest is a suspending function
  2. See if you can wrap the suspending function call in a coroutine & use the appropriate scope & dispatcher
    • e.g.,viewModelScope.launch can be used to wrap the suspending function call
  3. Remove thesuspend keyword from the function
  4. Remove creating coroutines from the caller of the function if it is not needed anymore

How to do

The example,

// In ViewModelsuspendfunlistenForUpdates(){listOfPlants.collectLatest{plants->plants.filter{it.isFavorite}.let{favorites->// do something with favorites}}}// In FragmentoverridefunonViewCreated(view:View,savedInstanceState:Bundle?){super.onViewCreated(view,savedInstanceState)lifecycleScope.launchWhenStarted{viewModel.listenForUpdates()}}
Enter fullscreen modeExit fullscreen mode

could be refactored to,

// In ViewModelfunlistenForUpdates(){viewModelScope.launch{listOfPlants.collectLatest{plants->plants.filter{it.isFavorite}.let{favorites->// do something with favorites}}}}// In FragmentoverridefunonViewCreated(view:View,savedInstanceState:Bundle?){super.onViewCreated(view,savedInstanceState)lifecycleScope.launchWhenStarted{viewModel.listenForUpdates()}}
Enter fullscreen modeExit fullscreen mode

References


Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Enthusiastic programmer, working as Android developer building custom Android Images (AOSP) and apps.
  • Location
    Dallas, Tx
  • Education
    Masters of Computer Science
  • Joined

More fromSubbu Lakshmanan

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp