Initially i am getting list data from network and store it in room db.
It is One to Many Relationship. For that i have created Two Tables and One Relationship data class
Product Table :
@Entity(tableName = "Product")
data class Products (
@PrimaryKey(autoGenerate = false)
@ColumnInfo(name = "id")
var id : Int = 0,
@ColumnInfo(name = "name")
var name : String? = null,
@ColumnInfo(name = "category_id")
var category_id : String? = null,
@ColumnInfo(name = "subcategory_id")
var subcategory_id : String? = null,
@ColumnInfo(name = "variants")
var variants : List<Variants> = listOf()
)
Variant Table :
@Entity(tableName = "Variant")
data class Variants (
@PrimaryKey(autoGenerate = false)
@ColumnInfo(name = "id")
var id : Int = 0,
@ColumnInfo(name = "product_id", index = true)
var product_id : Int? = null,
@ColumnInfo(name = "measurement")
var measurement : String? = null,
@ColumnInfo(name = "price")
var price : String? = null
)
Product With Variants ( Relationship between Two Tables )
data class ProductWithVariants(
@Embedded val product: Products,
@Relation(
parentColumn = "id",
entityColumn = "product_id"
)
val variants: MutableList<Variants>
)
Dao : I get the ProductsWithVariants data using query and also filter by subcategory_id
@Transaction
@Query("SELECT * FROM Product WHERE subcategory_id=:subcat")
fun getProductWithVariants(subcat:Int): Flow<MutableList<ProductWithVariants>>
ViewModel :
var productListN: Flow<MutableList<ProductWithVariants>> = flowOf(mutableListOf())
fun networkproductlist() = viewModelScope.launch(Dispatchers.IO) {
productist.collectLatest {
when (it) {
Resource.Empty -> {
Log.e("product", "" "empty")
}
is Resource.Failure -> {
Log.e("product", "" "failure")
}
Resource.Loading -> {
}
is Resource.Success -> {
val response = it.value
for (i in 0 until response.data.size) {
val product: Products = response.data.get(i)
for (j in 0 until product.variants.size) {
variants = product.variants.get(j)
}
}
productsDao.deleteAllProducts()
productsDao.insertProducts(response.data)
productsDao.insertVariants(variants!!)
val subcategoryid = SubCategoryList(response.data[0].subcategory_id!!.toInt())
productsDao.insertSubCat(subcategoryid)
productListN = productsDao.getProductWithVariants(response.data[0].subcategory_id!!.toInt())
Log.e("product","product in room viewmodel : $productListN")
}
}
}
}
As I said earlier , got the network response in success resource and insert products and variants in respective tables after that i insert the product subcategory in my database and get the list of ProductWithVariants by hit the getProductWithVariants() on the next line ..
The Problem here is now - i always get kotlinx.coroutines.flow.SafeFlow@f06e8a9 as a response of productlistN
Main Activity :
lifecycleScope.launch(Dispatchers.Main) {
proadapter = ProductAdapter()
binding.ProductRecyclerView.apply {
adapter = proadapter
}
}
lifecycleScope.launch(Dispatchers.Main) {
viewModel.productListN.collect {
println("Received UserInfo List $it")
proadapter.setMutableArraylist(it)
proadapter.notifyDataSetChanged()
}
}
CodePudding user response:
I found a couple of issues in your code:
- In
ViewModel
you usevar productListN = ...
and then reinitialize it with a new objectproductListN = productsDao.getProductWithVariants(response.data[0].subcategory_id!!.toInt())
. You shouldn't reinitialize it, you must use the same object. You can try to useStateFlow
orSharedFlow
to emit data:
val productListN: Flow<MutableList<ProductWithVariants>> = StateFlow(mutableListOf())
...
productListN.value = ...
- In
Activity
initializeproadapter
andbinding.ProductRecyclerView
outside oflaunch
function, and for collectingFlow
data just uselifecycleScope.launch { ... }
:
proadapter = ProductAdapter()
binding.ProductRecyclerView.apply {
adapter = proadapter
}
lifecycleScope.launch {
viewModel.productListN.collect {
println("Received UserInfo List $it")
proadapter.setMutableArraylist(it)
proadapter.notifyDataSetChanged()
}
}