I am using a viewModel to pull livedata from a room data base. I have 2 LiveData that I pull from my viewModel and then I will run a function to pull data from my server. I need both values to be set before running my function that will get info from my server because these values are part of the body of the post.
This is part of my activity
var locationSeleted:Long=0L
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView<ActivityBinding>(this,R.layout.activity)
//This is to get the viewmodel
val application = requireNotNull(this).application
val dataSource = Database.getInstance(application).DatabaseDao
val viewModelFactory = ViewModelFactory(dataSource, application)
val ViewModel = ViewModelProviders.of(this,viewModelFactory).get(ViewModel::class.java)
binding.ViewModel = ViewModel
binding.setLifecycleOwner (this)
//Get location from livedata
ViewModel.Location.observe(this, Observer {location ->
if (location == null){
//do something
}
else{
locationSeleted = location.locationId
}
})
//listens to the live data of the products value
ViewModel.Products.observe(this, Observer{products ->
if (products == null){
//do something
}
else{
myfunction(products)
}
})
This is part of my viewmodel
class ViewModel(val database: DatabaseDao, application: Application) : AndroidViewModel(application) {
//This gets the location selected
var Location: LiveData<LocationSelect> = database.get_location()
//This line gets the products
var Products: LiveData<Array<Products>> = database.get_products()
My current code works but I can imagen that if Location LiveData is delayed then myfunction will run with no location and the Post call will false. My question is how can I call myfunction when both location and products set from the viewModel? or is there a better way of doing this.
Thanks you
How many times can I observe? In theory, we can observe livedata with multiple observers, just like the good old pub-sub pattern, right? Well, let's test this out. Let's create a super simple livedata.
Use LiveData with RoomThe generated code runs the query asynchronously on a background thread when needed. This pattern is useful for keeping the data displayed in a UI in sync with the data stored in a database.
StateFlow and LiveData have similarities. Both are observable data holder classes, and both follow a similar pattern when used in your app architecture. The StateFlow and LiveData do behave differently: StateFlow requires an initial state to be passed into the constructor, while LiveData does not.
You can use a MediatorLiveData so you only have to observe one thing, and it fires only when both items are received, and on every change after that.
In the ViewModel:
val locationAndProductsLiveData: LiveData<Pair<LocationSelect, Array<Products>>> =
object: MediatorLiveData<Pair<LocationSelect, Array<Products>>>() {
var location: LocationSelect? = null
var products: Array<Products>? = null
init {
addSource(Location) { location ->
this.location = location
products?.let { value = location to it }
}
addSource(Products) { products ->
this.products = products
location?.let { value = it to products }
}
}
}
In your Activity:
ViewModel.locationAndProductsLiveData.observe(this) { (location, products) ->
locationSelected = location.Id
myFunction(products)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With