Lets take the following example:
A many to many mapping exists for PRODUCTS and ORDERS. So a product can be on multiple orders and an order can have multiple products. In Room I have an entity which has both the product id and order id as foreign keys so I can save the relations. It's now very easy to get all the orders for a specific product and also all the products for a specific order.
Now here comes the trouble. As far as I know there is no way to get the order object with all of it's products in 1 query/entity. This can be read in further detail in this post. In most places I can bypass this by just running two queries. The first to get the order I'm interested in, and the second to get the products based on the Id of the order.
Now I want to display the combination of an order with its products in an adapter. For that I need to combine all my orders with their products. I'm clueless on how to solve this with LiveData.
The best solution in my opinion would be to create one query that fetches the OrderWithProducts directly from the database. This post suggests it should be possible, but I've not managed to get this to work. Also the most crucial part in that example is missing: the OrderItem class.
If that solution is not possible there must be some way to get the LiveData OrderWithProducts list with 2 queries and somehow combine them.
EDIT After the suggestions of @Demigod now I have the following in my ViewModel:
// MediatorLiveData can observe other LiveData objects and react on their emissions.
var liveGroupWithLights = MutableLiveData<List<GroupWithLights>>()
fun createOrdersWithProducts() {
appExecutors.diskIO().execute {
val ordersWithProducts = mutableListOf<OrderWithProducts>()
val orders = orderRepository.getGroupsSync()
for (order in orders) {
val products = productRepository.getProductsSync(order.id)
val orderWithProducts = OrderWithProducts(order, products)
ordersWithProducts.add(orderWithProducts)
}
liveGroupWithLights.postValue(ordersWithProducts)
}
}
The function inside my fragment to submit data to the adapter:
private fun initRecyclerView() {
orderListViewModel.getOrdersWithProducts().observe(this, Observer { result ->
adapter.submitList(result)
})
}
So now I'm able to have a OrderWithProduct object as the item for my adapter. This is great, I can use products for each order in my adapter. Now I'm having trouble to update these items whenever the values in the database changes. Any ideas for this part?
Edit2: the invalidationtracker
db.invalidationTracker.addObserver(object : InvalidationTracker.Observer("orders", "products", "order_product_join") {
override fun onInvalidated(tables: MutableSet<String>) {
createOrdersWithProducts()
}
})
The problem I have now is that the validation tracker gets notified a lot for a single change.
>. So I would first have to fetch the LiveData
– Beuz Aug 01 '18 at 09:04> and add the LiveData
> to each order. How would I do that?
. In which code are you interested?
– Beuz Aug 02 '18 at 17:14