1

I am currently learning Paging 3 library. I have an app that has shimmer placeholder for showing while loading the data. When i get the data i want to hide shimmer layout and show recycler view.

lifecycleScope.launch {
            quoteViewModel.getQuotes2().collectLatest {
                binding.shimmerLayout.visibility = View.GONE // this line gets executed when view created and it causes shimmer layout to hide
                binding.homeRecyclerView.visibility = View.VISIBLE
                homeAdapter.submitData(it)
                Log.d("mytag", "after submit data") // this line isn't executed
            }
        }

Problem here is the line after the submitData doesn't get executed.I searched and saw the reason was because submitData never returns so it doesn't get called. But i didn't find any example code. Can someone please show me an example code for solving this?

The logic i want to execute after submitData is to hide shimmerLayout and show recyclerView, but because that logic is before submit data, they are executed immediately, therefore shimmerLayout doesn't seem when loading data.

nasibeyyubov
  • 1,735
  • 3
  • 11
  • 28

2 Answers2

1

As you mentioned, it is true that the line after submitData() won't be executed since it doesn't return. What is it exactly that you are wanting to achieve using Paging 3 with it here?

I had a similar doubt where my recyclerview was not updating data fetched from Paging 3 because I was using collect operator. Dustin Lam, the author of Paging 3 library answered me here to replace the collect with collectLatest and that had fixed the issue for me.

In your case, you are already using collectLatest. One quick fix can be to put the submitData at the very end of collectLatest since that is what causes the issue.

As mention in the collectLatest definition,

Terminal flow operator that collects the given flow with a provided action. The crucial difference from collect is that when the original flow emits a new value then the action block for the previous value is cancelled.

Note that replacing collect with collectLatest fixed the issue for my case only because initially my StateFlow was emitting an Initial state, but when the data was ready, it emitted a Success state that wasn't collected by the collect operator since the submitData never returns, but collectLatest forces the previous action block to be cancelled and new value to be collected.

I'm unsure of a solution to your problem yet but either edit your question with the exact use case or in case you do not find any alternative to it, you can directly ask Dustin Lam about it like I did :)

mehul bisht
  • 682
  • 5
  • 15
  • The logic i want to execute after submitData is to hide shimmerLayout and show recyclerView, but because that logic is before submit data, they are executed immediately, therefore shimmerLayout doesn't seem when loading data.(updated question) In your case if i move submitData out of collectLatest, then it will execute immediately when lifecycleScope.launch will be executed and no data will be given as parameter :( – nasibeyyubov Jul 26 '21 at 17:23
  • 1
    I don't think the order should matter here since setting the `visibility` and calling `submitData` in this order should be working as expected. What is the issue that you are facing by doing it the way you showed the code in the question with submitData at the end? :) – mehul bisht Jul 26 '21 at 18:54
  • because collectLatest is executed doesn't matter if there is any data or not. I mean it executes immediately view created, and shimmerLayout.visibility = View.GONE line executes immediately, that is why user don't see loading placeholder – nasibeyyubov Jul 27 '21 at 06:47
  • 1
    Ok I got your issue, this problem is very simple to solve. Just edit your question and add the code for `getQuotes2()` inside your `quotesViewModel`. I believe you are using `StateFlows` since you are using the `collectLatest`. There is a better approach to know the `loading` status of the network request and show the shimmer animation. :) – mehul bisht Jul 27 '21 at 07:02
  • yeah, you are right, i implemented using NotLoading state for hiding shimmer layout and it works just fine :) , thanks too much – nasibeyyubov Jul 27 '21 at 07:09
  • great to hear it helped to fix the issue :) – mehul bisht Jul 27 '21 at 07:27
1

I tried with: submitData(lifecycle, it) and it started to stop onto the lines after the Submit. Here says: Caution: The submitData() method suspends and does not return until either the PagingSource is invalidated or the adapter's refresh method is called. This means that code after the submitData() call might execute much later than you intend.

Ahmed Ahmedov
  • 592
  • 12
  • 29