'How to Unsubscribe from coroutine flows right after RoomDb call
I'm trying to query Room database(action 1) and then based on the returned results perform another action on the same table. however I noticed that every time I perform the second action, coroutine will query the database(action 1). but this is not I want. just as an example:
My ItemDao:
@Query("SELECT * FROM item_table")
fun selectItems():Flow<List<Item>>
@Insert
suspend fun insertItem(item:Item)
for example I want to perform selectItems()
first and if the list is empty immediately call insertItem(item)
fun insertIfListEmpty(item:Item){
val job=CoroutineScope(IO).launch {
itemDao.selectItems().collect{
log.d(TAG,"items collected")
if (it.isNullOrEmpty()) {
itemDao.insertItem(item)
}
}
}
}
but after itemDao.insertItem(item)
it shows log message again.even if I call itemDao.insertItem(item)
from another method again it shows log message. is there any way to unsubscribe the coroutine right after collect?
Solution 1:[1]
You can create additional method in the ItemDao
, which will return the number of elements, and then check if it equals to 0 then insert data.
ItemDao:
@Query("SELECT COUNT(*) FROM item_table")
suspend fun getItemCount(): Int
Function:
fun insertIfListEmpty(item: Item) {
someCoroutineScope.launch {
if (itemDao.getItemCount() == 0) {
itemDao.insertItem(item)
}
}
}
Solution 2:[2]
In the collect body, you can throw a cancellation exception
yourFlow.collect {
throw kotlinx.coroutines.CancellationException()
}
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 |
Solution 2 | Islam Assem |