I've been going through a Google sample app about Paging & mediator and I found an interesting flow map lambda case. You can find it below it is marked with a **.
I would assume that pagingData -> X.func would have the map return whatever the type is of X.func. But in this case, it's not.
pagingData is of type PagingData.
pagingData.map { UiModel.RepoItem(it) } should return a UiModel.RepoItem,
but according to the next map statement, the element has been converted to a PagingData<UiModel.RepoItem>. Shouldn't it be a UiModel.RepoItem?
repository.getSearchResultStream(queryString)
**.map { pagingData -> pagingData.map {UiModel.RepoItem(it) } } **
.map {
it.insertSeparators { before, after ->
if (after == null) {
// we're at the end of the list
return@insertSeparators null
}
if (before == null) {
// we're at the beginning of the list
return@insertSeparators UiModel.SeparatorItem("${after.roundedStarCount}0.000+ stars")
}
// check between 2 items
if (before.roundedStarCount > after.roundedStarCount) {
if (after.roundedStarCount >= 1) {
UiModel.SeparatorItem("${after.roundedStarCount}0.000+ stars")
} else {
UiModel.SeparatorItem("< 10.000+ stars")
}
} else {
// no separator
null
}
}
}
Here is the repository flow generating the flow. However, you do not need to read this it's not relevant.
fun getSearchResultStream(query: String): Flow<PagingData<Repo>> {
Log.d("GithubRepository", "New query: $query")
// appending '%' so we can allow other characters to be before and after the query string
val dbQuery = "%${query.replace(' ', '%')}%"
val pagingSourceFactory = { database.reposDao().reposByName(dbQuery) }
@OptIn(ExperimentalPagingApi::class)
return Pager(
config = PagingConfig(pageSize = NETWORK_PAGE_SIZE, enablePlaceholders = false),
remoteMediator = GithubRemoteMediator(
query,
service,
database
),
pagingSourceFactory = pagingSourceFactory
).flow
}
Calling
map
on a Flow gives you another Flow with a different type. Callingmap
on a PagingData gives you another PagingData with a different type.The inner
map
call converts the PagingData's type from one thing to another, but you still have a PagingData in the end.Taking this line:
And breaking it apart, we can see what's happening.