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")
pointAdapter.submitData(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)
}.flow.cachedIn(viewModelScope)
}
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
OK
override fun areItemsTheSame(oldItem: PointsItem, newItem: PointsItem): Boolean =
oldItem.id == newItem.id
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
@SerializedName("eventDate")
val eventDate: String?,
@SerializedName("eventId")
val eventId: String?,
@SerializedName("group")
val group: String?,
@SerializedName("iconName")
val iconName: Any?,
@SerializedName("name")
val name: String?,
@SerializedName("points")
val points: Double?,
@SerializedName("transactionAmount")
val transactionAmount: Double?,
@SerializedName("transactionCurrency")
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)
}.flow.cachedIn(viewModelScope)
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?
ah
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
window
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
OK
Hi Sudokai
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