'Confused about official Android documentation on Flow

I refer to the official Android documentation on using the Flow library in the recommended app architecture.

In the UserRepository class:

class UserRepository @Inject constructor(...) {
   fun getUser(userId: String): Flow<User> {
       refreshUser(userId)
       // Returns a Flow object directly from the database.
       return userDao.load(userId)
   }

   private suspend fun refreshUser(userId: String) {
       ...
   }

   ...
}

I don't understand how refreshUser(), which is a suspending function, can be called in getUser(), which is a non-suspending function. Perhaps I'm missing something.

I'm trying to create something very similar to this class and, as expected, I get a compilation error stating that the suspending function can be called only in another suspending function. What is the minimal change required to make this work, such that in UserProfileViewModel, I can keep the LiveData<User> variable user as it already is:

val user = userRepository.getUser(userId).asLiveData()


Solution 1:[1]

You can't call a suspend function within non-suspend function, so the function getUser() has an error Suspend function 'refreshUser' should be called only from a coroutine or another suspend function. To make this error disappear add suspend keyword:

suspend fun getUser(userId: String): Flow<User> { ... }

To make your second code work you need to use liveData builder.

val user = liveData<User> { 
    emitSource(getUser(userId).asLiveData())
}

In liveData builder you can call suspend functions, in particular getUser(userId).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 BigSt