I have an app that use fragments, navigation and viewModels. I cannot call a query "getCustomerById" from my view model (CustomerViewModel.kt). More details: I am selecting customer from CustomerFragment which opens CustomerDetailFragment and display details about customer. I am using a common ViewModel for both fragments. Most of the things work, but I cannot get my query (getCustmoerbyID) to work from CustomerDetailsFragment. I have a compiler error. The code looks like this.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val customer = customerViewModel.geCustomerById("11")
Log.i(Constants.LOG_TAG, "Customer details fragment. ${customer.first().firstName}. Done ** onViewCreated. **")
}
The error is in the log statement, for method first(). "Suspend function 'first' should be called only from a coroutine or another suspend function"
Same issue with "getCustomerCount". I have spent hours or days on it, because of my lack of knowledge of Coroutines. I cannot put code from original app, so I have put a simplified app on github. The link is as follows.
CodePudding user response:
You need to launch a coroutine to call suspend
function Flow.first()
. In Activity
or Fragment
you can use lifecycleScope
, in ViewModel - viewModelScope
to launch a coroutine. Example:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
lifecycleScope.launch {
val customer = customerViewModel.geCustomerById("11")
val name = customer.first()?.firstName;
// ... use name
}
}