Can we pass a Flow inside an UiState? It that acce...
# android
g
Can we pass a Flow inside an UiState? It that acceptable for paginated results?
b
Yes, it is acceptable to pass a
Flow
inside a UI state, especially for paginated results. Using a
Flow
in your UI state allows you to handle asynchronous and reactive updates to your data. When dealing with paginated results, a common approach is to use a
Flow
to represent the data stream. As new pages of data are fetched, the
Flow
emits updated results, and you can update your UI accordingly. By including the
Flow
in your UI state, you can observe it in your UI layer and react to any changes.
Ex
Copy code
data class UiState(
    val data: Flow<List<Item>>,
    val isLoading: Boolean,
    val error: Throwable?
)
g
Awesome, thank you
d
What speaks against updating the UIState as the paginated data comes in?
☝️ 1
m
@Bilagi I do not agree with your proposal. Are you aware of what’s happening with the data classes behind the hood? I’m talking about the
copy()
,
toString()
,
equals()
, etc methods. I wonder how the compiler would react to Flow for comparing or checking its data. You’re passing a Flow inside a data class, and you shouldn’t. Consider checking MutableStateFlow or StateFlow for that purpose, and use sealed interfaces to pass the UI state to your Composables. Also, don’t forget about the
collectAsStateWithLifecycle()
g
@Mohsen What I mean here is that there's of course a StateFlow for the UIState data class observed via
collectAsStateWithLifecycle()
, but within it, I need paginated results that come from Paging3 directly used into my screen so I can call this function from paging-compose. While the paginated results do change the data of the UIState stays the same, so I don't need to update the UIState, and it does seems to work!
m
I underestand, but in programming, especially when it comes to Android and working with Kotlin, “_and it does seems to work_!” does not mean that it is the right solution only because it works.
I understand, but in programming, especially when it comes to Android and working with Kotlin, “and it does seems to work!” does not mean that it is the right solution only because it works.
1
g
Hmm. I'll add something. • You're somewhat right because it turns out that when copying the UI State, I needed to be careful to not return a new flow each time because then the PagingData needs to start to load from scratch each time the UIState is copied, making list blink multiple times
You're somewhat right because it turns out that when copying the UI State, I needed to be careful to not return a new flow each time (and reuse the one already in the state) because then the PagingData needs to start to load from scratch each time the UIState is copied, making our list blink multiple times. I really like the fact that that paging flow is scoped to the right class in the sealed hierarchy of the UIState. Saying "Show an error now" but "hey here's anyway the flow you need for the pagination, but because we're in error its empty so just don't look at it" doesn't feel right. BTW, when you'll have been working so long on Android like me, I can tell you that generally, something that works is usually what is needed and more than that is a mistake introduce in your code, but each to their own :) So right now, it *works perfectly (*how's that for wording?)
m
“something that works is usually what is needed” There are two sides of this topic: 1. It depends on the company you’re working for. Sometimes some companies they just need an MVP and don’t really care if we’re using the right code for a specific issue. I wonder what’s gonna happen to code reviews, and if you can even pass that stage with this solution. 2. In my opinion, not using the right code might cause confusion and this is not expected from a senior or tech lead developer. In the future, you’ll again need to refactor this once the MVP is done and you have time to spent. Generally speaking, I know what you’re trying to do,
collectAsLazyPagingItems()
extension function receives a type of
Flow<PagingData<T>>
. You should be able to use another more convenient and reasonable solution for this instead of passing a
Flow
inside a Data class in which the parameter is immutable. Flow is mutable.
👏 1