combining pagingData 3 flow with another flow
Asked Answered
A

1

8

I have a pagingData flow object and i want to combine it with a different flow of fused location so it will be processed accordingly with each item of the pagingdata list .

val point : Flow<Point> 
val pagingDate : Flow<PagingData>

i tried to use combine and combineTransform but it seem to not work as when the point is updating app crashes and shows this error message related to pagingData 3 can't be emited twice

java.lang.IllegalStateException: Attempt to collect twice from pageEventFlow, which is an illegal operation. Did you forget to call Flow<PagingData<*>>.cachedIn(coroutineScope)?

what are my options here to transform pagingdata items with streamed data ?

Arcograph answered 18/2, 2021 at 14:59 Comment(1)
Can you share your usage of .combine and the overall operator chain against Flow<PagingData>?Slideaction
S
6

Just following up here since others may hit this issue although OP didn't update their answer yet.

This is typically due to usage of .combine or similar operators which would repeat the latest emitted value from a Flow, causing the same instance to be used twice. To prevent this you can call .cachedIn(scope) before .combine() so that the Flow is multicasted, giving you a new instance of PagingData with cached data preloaded.

Slideaction answered 26/2, 2021 at 1:26 Comment(5)
Thanks a lot for this! For those wondering, it seems like calling cachedIn(scope) twice is acceptable as well. So this code works perfectly fine:- pagedFlow = repository.getPagedData().cachedIn(scope).combine(otherFlow) { // Your UI transformations here }.cachedIn(scope)Dunois
If your transformation is trivial, you may want to be careful of the number of items you are buffering or at least create a smaller scope to cache them in as opposed to viewModelScope... depending on the number of times you expect .combine() to triggerSlideaction
Yeah, I had tried different solutions for this but unfortunately, my transformations are not trivial (transforming to UI model and adding separators). The other flow used in .combine() won't change during paging, it can change only when the user modifies an entry from some other part of the app. So, combine() will mainly be called only when paging data loads. I will see if I can try using some other scope for caching though.Dunois
Also, for app performance, I have noticed calling cachedIn() after the transformations has significant positive impact. The items being loaded are relatively lightweight (basic data class, no images) but the no. of items can be very large.Dunois
I feel uneasy about it as Paging codelabs say that cachedIn() should be used as a terminal operator. Can somebody explain what exactly happens if you call it twice? What are downsides?Blairblaire

© 2022 - 2024 — McMap. All rights reserved.