Search code examples
androidkotlinpaginationandroid-viewmodelandroid-mvvm

How to store Pagination data in ViewModel Android?


On rotating the device I am losing the previous page loaded page data. How can I resolve this?

With below implementation, only the data of the current page is persisted in the ViewModel but all other pages are lost. Any solution for this?

API response (Page 1) http://www.mocky.io/v2/5ed20f9732000052005ca0a6

ViewModel

class NewsApiViewModel(application: Application) : AndroidViewModel(application) {

    val topHeadlines = MutableLiveData<TopHeadlines>()
    var networkLiveData = MutableLiveData<Boolean>()

    fun fetchTopHeadlines(pageNumber: Int) {
        if (!getApplication<Application>().hasNetworkConnection()) {
            networkLiveData.value = false
        }
        val destinationService = ServiceBuilder.buildService(DestinationService::class.java)
        val requestCall = destinationService.getTopHeadlines(AppConstants.COUNTRY_INDIA, AppConstants.PAGE_SIZE, pageNumber, AppConstants.NEWS_API_KEY)
        requestCall.enqueue(object : Callback<TopHeadlines> {
            override fun onFailure(call: Call<TopHeadlines>, t: Throwable) {
                Log.e("ANKUSH", "$t ")
            }

            override fun onResponse(call: Call<TopHeadlines>, response: Response<TopHeadlines>) {
                if (response.isSuccessful) {
                    topHeadlines.postValue(response.body())
                }
            }
        })
    }

}

MainActivity

fun observeAndUpdateData() {
        activity.viewModel.topHeadlines.observeForever {
            isDataLoading = false
            checkAndShowLoader(isDataLoading)
            if (AppConstants.STATUS_OK == it.status) {
                it.articles?.let { articles ->
                    if (articles.size < AppConstants.PAGE_SIZE) {
                        activity.isAllDataLoaded = true
                    }
                    activity.adapter.updateData(articles)
                }
            }
        }
    }

fun getTopHeadlines(pageNumber: Int) {
        if (activity.isAllDataLoaded) return
        isDataLoading = true
        checkAndShowLoader(isDataLoading)
        activity.viewModel.fetchTopHeadlines(pageNumber)
    }

Solution

  • You just need to store the current page and the data you gathered in a list in the ViewModel.

    So don't pass the page number to the fetchTopHeadlines function, instead, consider having a private global variable in the ViewModel and everytime that you call the fetchTopHeadlines, increment the page number too.

    Also to prevent loss of previous pages, Consider having an ArrayList in your ViewModel. After fetching the data from server, first put all your data in the list defined in the ViewModel and then publish that list to your View.

    Here is a sample that helps you dealing with it.