Android paging library with clean architecture
A

1

28

I was trying the paging library from Android Architecture Component but I have doubts integrating it in a clean architecture based project.

Generally I have 3 modules:

  • Main Module (App)
  • Data Module (Android module with network and db dependencies)
  • Domain Module (Pure Kotlin Module)

In order to introduce pagination, I had to consider PagedList<T> class as a domain class. (IMO is not a terrible idea since in the end is a list and the data source is abstracted)

So in the domain layer I can have a repostiory like:

interface ItemRepository {
    fun getItems():PagedList<Item>
}

And then in the data module create the implementation like this:

class ItemRepositoryImpl: ItemRepositoy(private val factory:ItemDataSourceFavtory) {
    fun getItems():PagedList<Item> {

  val pageConfigurations = PagedList.Config.Builder()
            .setPageSize(10)
            .setInitialLoadSizeHint(15)
            .setPrefetchDistance(5)
            .setEnablePlaceholders(false)
            .build()

    return RxPagedListBuilder(locationDataSourceFactory, pageConfigurations)
            .setInitialLoadKey(1)
            .buildObservable()
}

So far so good. My doubt is when we need to transform the domains model for the presentation layer (let's say my item needs to be aware if was checked to show a checked Icon) normally I would map my domain model into a presentation one.

Im aware DataSourceFactory has map and mapByPage methods, but the factory resides in the data layer. My Viewmodel consumes data from the model layer which in this cases would be a PagedList, and as far as I know, paged list doesn´t support mapping.

So what would be the appropiate thing to do in this situation?

Abuse answered 27/5, 2018 at 1:45 Comment(3)
I faced the same problem today and i couldn't able to find any sample, I think paging library cannot be integrated with clean code architecture.Adenoma
@Marco Pierucci How did you add android lib (paging) to the kotlin module (domain)? is it even possible?Quach
Also have a look at https://mcmap.net/q/504867/-map-flow-of-pagingdata-to-another-model/4134215Yasmineyasu
L
6

You cannot map PagedList into presentation model, since PagedListAdapter need the PagedList to load next/previous pages.

The PagedList have two main function, firstly it's a data structure to hold a List of items that are paged (Part present and part absent), using snapshot() you can easily get the present items, map domain model into a presentation one and pass it to the ListAdapter to show list of items.

Secondly it has to alert DataSource when more pages are needed. PagedListAdapter receive a PagedList, and upon binding items it depend on loadAround() method of PagedList to detect when new pages are needed.

DISCLAIMER: This is just my opinion and open to discussion but PagingLibrary is not a clean solution by default, the easiest way is to map domain model inside DataStore upon fetching them (either network or db) and pass the PagedList with the presentation models to the presentation layer. Mapping PagedList itself is not logical (though possible) as it is tightly coupled with PagedListAdapter in View.

Limitary answered 30/6, 2018 at 8:56 Comment(2)
how do you define a DataStore that maps between database entities and presenttaion models?Alpaca
@Alpaca if you are using PagingData<T> with paging library 3 you can just map it twice to get to the model like this Pager( config = PagingConfig( pageSize = 20, enablePlaceholders = false, ), remoteMediator = NewsRemoteMediator(newsDataBase, api), pagingSourceFactory = pagingSourceFactory ).flow.map { it -> it.map { it.toDomain() } }Schaper

© 2022 - 2024 — McMap. All rights reserved.