My viewModel refetches my data causing my shimmer to keep executing each time I get to this fragment, and also the data is beign refetched which is making my bill goes up on Firebase
How can I prevent to refetch again the data each time my fragment pops up ?
viewModel.fetchShops(location).observe(viewLifecycleOwner, Observer {
when(it){
is Resource.Loading -> {
shimmer.visibility = View.VISIBLE
shimmer.startShimmer()}
is Resource.Success -> {
shimmer.visibility = View.GONE
shimmer.stopShimmer()
adapter.setItems(it.data)
}
is Resource.Failure -> {
Toast.makeText(requireContext(),"Error fetching data",Toast.LENGTH_SHORT).show()
}
}
})
I call this in my onViewCreated()
so each time this fragment recreates my Resource.Loading
fires as well as the fetchShops(location)
and this fetches again to my database, I want it to fetch just once each time I come back to this fragment, any idea?
fun fetchShops(location:String) = liveData(Dispatchers.IO) {
emit(Resource.Loading())
try{
emit(repo.fetchShops(location))
}catch (e:Exception){
emit(Resource.Failure(e))
}
}
You're creating a new LiveData
instance every time fetchShops()
is called. This means that any previously created LiveData
(and the previous value it stores) is lost.
Instead, you should Transform your LiveData by using your location
as the input into creating your liveData { }
block as per the liveData
with Transformations
.
private val locationQuery = MutableLiveData<String>
// Use distinctUntilChanged() to only requery when the location changes
val shops = locationQuery.distinctUntilChanged().switchMap { location ->
// Note we use viewModelScope.coroutineContext to properly support cancellation
liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
emit(Resource.Loading())
try{
emit(repo.fetchShops(location))
}catch (e:Exception){
emit(Resource.Failure(e))
}
}
}
fun setLocation(location: String) {
locationQuery.value = location
}
You can then use this by updating your Fragment:
// Set the current location
viewModel.setLocation(location)
// Observe the shops
viewModel.shops.observe(viewLifecycleOwner, Observer {
when(it){
is Resource.Loading -> {
shimmer.visibility = View.VISIBLE
shimmer.startShimmer()}
is Resource.Success -> {
shimmer.visibility = View.GONE
shimmer.stopShimmer()
adapter.setItems(it.data)
}
is Resource.Failure -> {
Toast.makeText(requireContext(),"Error fetching data",Toast.LENGTH_SHORT).show()
}
}
})