Hi there, i've a problem with Compose+PagingData. ...
# compose
b
Hi there, i've a problem with Compose+PagingData. In the viewModel I make the paging request and get the flow of pagingData. Then using the collectAsLazyPagingItems() I pass it to Composable. In the Compose I listen its loadStates. On loading i show a loading indicator, on notLoading i check the snapshot list size and if its empty i show the empty screen, if it is not empty i show the actual list with lazyColumn. So here the problem, when open the screen, first -> empty screen shows up, second -> loading indicator and finally the list comes up. So it kind of flicks and looks ugly. I want that the empty screen should only shows up when the request is over and no data. Thanks.
i already tried lazyItems.loadState.refresh.endOfPaginationReached and itemCount == 0. But refresh.endOfPaginationReached comes always false
j
Using loadState.append.endOfPaginationReached instead should do
b
loadState.append.endOfPaginationReached comes true before the data comes. So empty screen shows up before the list comes 😕
s
This should work for empty state:
Copy code
val LazyPagingItems<*>.finishedLoadingEmpty
  get() = loadState.append.endOfPaginationReached &&
    loadState.refresh is LoadState.NotLoading &&
    itemCount == 0
b
i tried this one also but it did not help. Below i attached the log when the user open the screen. emptyScreen shows up before the data comes because the lines that i highlighted. As you can see the data is not come yet but "refresh is NotLoading" and "append.endOfPaginationReached is true"
j
well that's weird, loadState.append.endOfPaginationReached being true before it starts loading definitely feels like a bug. I'm using it in my app and it works for me as expected though:
Copy code
loadState.refresh: NotLoading(endOfPaginationReached=false)
loadState.append: NotLoading(endOfPaginationReached=false)
itemCount: 0
===============================
loadState.refresh: Loading(endOfPaginationReached=false)
loadState.append: NotLoading(endOfPaginationReached=false)
itemCount: 0
===============================
loadState.refresh: NotLoading(endOfPaginationReached=false)
loadState.append: NotLoading(endOfPaginationReached=false)
itemCount: 200
===============================
loadState.refresh: NotLoading(endOfPaginationReached=false)
loadState.append: Loading(endOfPaginationReached=false)
itemCount: 200
===============================
loadState.refresh: NotLoading(endOfPaginationReached=false)
loadState.append: NotLoading(endOfPaginationReached=true)
itemCount: 285
b
yes thats the result i wish to see 😄 Can you share your viewmodel also please? How do you create and store your pagingData?
thats how i do it
j
I do it like this:
Copy code
// Inside viewModel:
val ratings = Pager(
    config = PagingConfig(...),
    initialKey = null,
    pagingSourceFactory = pagingSourceFactory,
).flow.cachedIn(viewModelScope)

// In composable:
val ratings = viewModel.ratings.collectAsLazyPagingItems()