如何使用挂起函数作为参数在视图模型中初始化流
How to initialize a flow in viewmodel with a suspend function as parameter
我正在使用房间数据库和数据存储。
这是我的代码
视图模型
@HiltViewModel
class SubscriptionViewModel @Inject constructor(
private val userDataStore: UserDataStore,
private val walletDao: WalletDao
) : ViewModel() {
val flow: Flow<List<Transaction>> = walletDao.getAllTransactions(userDataStore.getId())
// This shows an error as userDataStore.getId() is a suspend function in DataStore
init {
viewModelScope.launch(IO) {
getWalletAmount()
}
}
}
数据存储
suspend fun getId(): String {
val preferences = dataStore.data.first()
return preferences[USER_ID] ?: ""
}
WalletDao
@Query("SELECT * FROM recent_transactions where user_id=:user_id")
fun getAllTransactions(user_id: String): Flow<List<Transaction>>
问题是我无法初始化流程。我尝试使用 lateinit 在 init{ } 块中初始化它,但是在片段中访问时它崩溃了,说流尚未初始化。
任何解决方案都会有所帮助。
据我所知,您可以在变量中调用 suspend fun,它必须在 init 或函数中
还有一个解决方案
@HiltViewModel
class SubscriptionViewModel @Inject constructor(
private val userDataStore: UserDataStore,
private val walletDao: WalletDao
) : ViewModel() {
val flow= MutableStateFlow<List<Transcation>>(listOf())
// then add value in init or anywhere
init {
viewModelScope.launch(IO) {
flow.emit() // add value here
}
}
}
您可以将其包装在流生成器中。
val flow: Flow<List<Transaction>> = flow {
val source = walletDao.getAllTransactions(userDataStore.getId())
emitAll(source)
}
如果你想让它pre-load(甚至在任何东西收集流量之前就开始获取第一个值),那么你应该通过添加它把它变成一个 SharedFlow:
.shareIn(viewModelScope, SharingStarted.Eagerly, replay = 1)
我正在使用房间数据库和数据存储。 这是我的代码
视图模型
@HiltViewModel
class SubscriptionViewModel @Inject constructor(
private val userDataStore: UserDataStore,
private val walletDao: WalletDao
) : ViewModel() {
val flow: Flow<List<Transaction>> = walletDao.getAllTransactions(userDataStore.getId())
// This shows an error as userDataStore.getId() is a suspend function in DataStore
init {
viewModelScope.launch(IO) {
getWalletAmount()
}
}
}
数据存储
suspend fun getId(): String {
val preferences = dataStore.data.first()
return preferences[USER_ID] ?: ""
}
WalletDao
@Query("SELECT * FROM recent_transactions where user_id=:user_id")
fun getAllTransactions(user_id: String): Flow<List<Transaction>>
问题是我无法初始化流程。我尝试使用 lateinit 在 init{ } 块中初始化它,但是在片段中访问时它崩溃了,说流尚未初始化。
任何解决方案都会有所帮助。
据我所知,您可以在变量中调用 suspend fun,它必须在 init 或函数中 还有一个解决方案
@HiltViewModel
class SubscriptionViewModel @Inject constructor(
private val userDataStore: UserDataStore,
private val walletDao: WalletDao
) : ViewModel() {
val flow= MutableStateFlow<List<Transcation>>(listOf())
// then add value in init or anywhere
init {
viewModelScope.launch(IO) {
flow.emit() // add value here
}
}
}
您可以将其包装在流生成器中。
val flow: Flow<List<Transaction>> = flow {
val source = walletDao.getAllTransactions(userDataStore.getId())
emitAll(source)
}
如果你想让它pre-load(甚至在任何东西收集流量之前就开始获取第一个值),那么你应该通过添加它把它变成一个 SharedFlow:
.shareIn(viewModelScope, SharingStarted.Eagerly, replay = 1)