0

I have a login app which uses Navigation Activity, JetPack and RoomDB. It has LoginFragment, LoginVieweModel, LoginDatabase, LoginDao and login Repository. I don't know the correct syntax to get UserCount from RoomDB.

The whole app is located in GitHub at https://github.com/msyusuf/LoginFragNavActivity.git.

Code in LoginDao is

@Query("SELECT COUNT(*) FROM loggedin_user_table")
suspend fun getLoggedInUserCount(): Int

Code in LoginViewModel is

fun getUserCount(): Int {
    var count: Int = 99
    viewModelScope.launch {
        count = loginRepository.getUserCount()
        Log.i(LOG_TAG, "In LoginViewModel.getUserCount(): count = $count")
    }
    return count
}

The fun getUserCount() does not have count from repository, it 99 which I used to initialize the count variable.

Sergio
  • 27,326
  • 8
  • 128
  • 149
Saleem
  • 145
  • 1
  • 9
  • Your launched coroutine will not happen until after `getUserCount()` has returned. Have your viewmodel provide the data via some reactive mechanism, such as by having `getUserCount()` itself be a `suspend` function. – CommonsWare Apr 24 '22 at 23:20
  • Some explanations here: https://stackoverflow.com/a/68370029/506796 – Tenfour04 Apr 25 '22 at 00:09
  • I found a solution on Stack Overflow ( https://stackoverflow.com/questions/52057041/how-to-get-the-row-count-of-room-database-in-android) – Saleem Apr 25 '22 at 18:31
  • @Saleem I review answers by the link you provided, and most of them seems not good to me, except answers where `LiveData` is used, I wouldn't use them. There is a simpler solution, please check my answer. – Sergio Apr 25 '22 at 19:31

1 Answers1

1

In getUserCount() function of LoginViewModel class a coroutine, launched using launch builder, will be executed after the function returns. You should think about how you want to use the data. If you want it to be used just as an input data for some another calculations then it make sense to make the getUserCount() function suspend:

suspend fun getUserCount(): Int {
    val count: Int = loginRepository.getUserCount()
    Log.i(LOG_TAG, "In LoginViewModel.getUserCount(): count = $count")
    return count
}

If you want it to be displayed in UI you can make it suspend like above and call it in a coroutine using lifecycleScope:

in Activity/Fragment

lifecycleScope.launch {
    val count = viewModel.getUserCount()
    // update UI
}

Another alternative is to apply reactive approach using LiveData or Kotlin Flow

Sergio
  • 27,326
  • 8
  • 128
  • 149
  • Thank you, Sergey. At the moment, I have something that works, so I will stay with it and deal with the next problem. Later, when I get a chance, I will revisit. Thank you for you help. – Saleem Apr 26 '22 at 00:26