I have a recyclerview with load more, and I can't store the values in the database. So when I load the data, everything works perfectly. The problem occurs when I navigate to another fragment, and click onBackPressed, the onChanged of the observer is being called again and it is giving me the last values called from the API. Then as you can see in the code below, they are automatically being added to the list and published in UI
productsViewModel.productsObject.observe(viewLifecycleOwner, Observer { result ->
if (result.status != Status.LOADING) {
(activity as MainActivity?)!!.dismissProgressDialog(getView())
if (result.status == Status.SUCCESS && result.data != null) {
val productsResult = parseObject(result.data.asJsonObject)
if (!productsResult.isNullOrEmpty()) {
products.addAll(productsResult)
productAdapter.submitList(products)
progressBar.visibility = View.GONE
numberSearch.text = products.size.toString() + "/" + total + " " + resources.getString(R.string.items_found)
} else if (result.status == Status.ERROR) {
if (result.message.isNullOrBlank())
Utils.showSnackBar(requireContext(), view, getString(R.string.something_wrong_try_again), true)
else
Utils.showSnackBar(requireContext(), view, result.message, true)
}
}
}
})
I think that you are not observing your result
correctly.
For example, if the value of result
is Status.LOADING
what happens? After you enter that block, maybe there are other cases that you are not handling. We don't know because there is no other when
or else if
block.
Another way more "clean" would be:
productsViewModel.productsObject.observe(viewLifecycleOwner, Observer { result ->
when(result.status) {
Status.LOADING -> manageLoading()
Status.SUCCESS -> manageSuccess()
Status.ERROR -> manageError()
else -> manageBaseCase()
}
}
Thus, it is not all embedded in a unique if
block making the management more understandable.
In your Fragment you should manually send an event to "reset" the actual state of the LiveData so that you will be sure that there won't be duplicate items.
Your Fragment may look something like this:
class ProductsFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.product_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
observe()
productsViewModel.send(Event.Load)
}
}