Office Hours Transcript: 2021-07-10

IvanoNoSpaces joined

Hello Mark!

hello, Ivano!


how can I help you today?

sorry if I am asking a lot in this period, is the most delicate moment of my career, thank you very much today for your altruistic help on SO about my paging problem


Is my first real ticket on Flows and coroutines, and I cannot send the data from the paging to the adapter
I have a button and on click I trigger the paging “call” from the fragment to the view model
And I see that the adapter, namely the adapter.submitData(pagedData) is called only when I initialise the button on press, but not when the data are retrieved

This is myFragment

fragment_points_card_constraint_layout.setOnClickListener {
    GlobalScope.launch(Dispatchers.IO) {
        try {
            pointViewModel.fetchThat(openIdAuthHandler.getMWiseUserId.value!!).collectLatest { pagingData ->
                Timber.i("IVOZZ pagingData :$pagingData")

        } catch (e: Exception) {
            Timber.i(" IVOZZ exception flow: $e")

and this is the viewModel

class PointViewModel(val networkClient: NetworkClient) : ViewModel() {

    fun fetchThat(userId: String) = Pager(PagingConfig(pageSize = 1)){
        PointsTransactionsSource(networkClient, userId)

I think i run in an execution reactive problem, and cannot find why is happening

I can tell you that in my use of Paging 3, we do it a bit differently

partly, that is because this project is using RxJava more so than coroutines


partly, that is because we consider the PagingData to be part of the viewstate

ah i read that is possible to use also rxjava indeed, there are also dedicated dependencies


well will found a way to understand

translating our approach to your scenario, we have the ViewModel collect the PagingData and emit it via a LiveData


the fragment observes the LiveData and calls submitData() on the adapter


that way, if we undergo a configuration change, we are not forced to reload the data, as the PagingData is retained

yes I found this approach on the internet


anyway does not matter I would like to ask you about the diffCallback in the adapter

override fun areItemsTheSame(oldItem: PointsItem, newItem: PointsItem): Boolean = ==


as my object does not have any identifier, and as is still not working the adapter I added a bogus variable val id :Int? in the object


but was just to test


could you confirm that I can just use the diff util with oldItem == newItem for areItemsTheSame` ?

um, well, I cannot really answer that, as it depends a lot on what PointsItem is

without adding a fake id in the model /data class?

if PointsItem is a data class, then == says that the objects are equal if they have the same content

PointsItem is the list of objects that is coming from the back end and in principle does not have any identifier as an id


but just some proprieties

is it a data class?

yes it is

OK, then == will return true if all the properties have the same content

data class PointsItem(
    val id :Int,//temp
    val eventDate: String?,
    val eventId: String?,
    val group: String?,
    val iconName: Any?,
    val name: String?,
    val points: Double?,
    val transactionAmount: Double?,
    val transactionCurrency: String?

ah I see


thank you


and there is another thing I do not get although my researches


as you can see from the method in the VM i pasted above I give a PagingCOnfig parameter in this case pageSize 1 ```fun fetchThat(userId: String) = Pager(PagingConfig(pageSize = 1)){
PointsTransactionsSource(networkClient, userId)


the documentation says

     * Defines the number of items loaded at once from the [PagingSource].
     * Should be several times the number of visible items onscreen.
     * Configuring your page size depends on how your data is being loaded and used. Smaller
     * page sizes improve memory usage, latency, and avoid GC churn. Larger pages generally
     * improve loading throughput, to a point (avoid loading more than 2MB from SQLite at
     * once, since it incurs extra cost).

1 seems very small

yes I am experimenting


I will giggle a bit


well Mark still thank you for your help today here and in SO

I typically use 25 as a starting point and tune if needed

but this 25 what is in the old adapter world?

25 is the number of items that I want to retrieve from the data source as a "page"

is the size of the items showed before to load again swiping down?



in my case, I am accessing a Web service, the kind that take an offset and limit pair ("give me 25 items starting at offset 0")

I understand, so is me that decide how is a page in the PagingSource not the back end


ok thank you to share


this item makes things easier, was a nightmare before, but could not understand how the black magic was performed, now my ideas are a bit clearer

yes, Paging 3 is much better than Paging 1 was, in terms of its API, at least if you are developing in Kotlin

yes callback are toxic

I never successfully created a custom data source with Paging 1 – I only wound up using it with Room


Paging 3 is far simpler to create custom data sources

I know i went desperatly through all your books today


you did also something with graph sql

sorry, I do not have anything on custom Paging 3 data sources

about pagination but not with paging library


sorry? Mark you do miracles to update everything


is just that not being familiar I just tried to copy paste the tutorials could find and twickling them and prey


but now `i understand that is a beautiful library


tweaking* sorry

IvanoNoSpaces_reload joined

hello again!

hello again sorry my daughter took the mouse and closed the door



sudokai joined

hello, sudokai! the chat period is nearly over – do you have a quick question?

I can’t think of one


Just dropping by

That’s a wrap for today’s chat. The next one is Tuesday in the 8:30am US Eastern time slot.


have a pleasant day!

Bye Mark and Sudokai, thanks again


you too