My usecase is returning a flow. The data should be...
# android-architecture
b
My usecase is returning a flow. The data should be filtered by the the param. Should I make the param is a Flow too, that I can combine 2 flow PARAM + RESULT to return a flow of filtered result ?
For ex: GetMovieUseCase {
fun execute(paramFlow: Flow<GetMovieParam>): Flow<MovieModel> {
val movieFlow = movieRepo.getAll()
return paramFlow.combine(movieFlow) {
//Do some filtering logic here
}
}
d
Doesn't seem very convenient, especially to test. Why not passing a simple param and use the use case as
Copy code
paramsFlow.flatMap { params ->
  useCase.execute(params)
}
b
Because the flow gotten from repo is ColdFlow, if the param change I have to re-collect from flow.
So I just want to make it reactive to avoid re-collect the ColdFlow
g
Not necessary make param flow, instead I would do:
Copy code
fun execute(param: GetMovieParam): Flow<MovieModel> {  
   return movieRepo.getAll() // This return flow, right?
         .filter { 
           //Do some filtering logic here
         }
   } 
}
And user of this API does
Copy code
val paramFlow: Flow<GetMovieParam> = //Some way to get param

paramFlow.flatMapLatest {  execute(it) } // not necessary latest, but one which suits your use case
I think passing flow as params is not the best practice and better to split them into more simple building blocks
Also, just a side note, it looks better to pass param to movieRepo,.getAll(param) to avoid requesting unncessary data,
b
Thank for your kind and good explaination. I know flatMapLatest and combine has own usesage. For example, the data getting from repository is listing from socket…that server will returning full list of data. So in this case, I don’t wanna recollect the data flow (Socket) because it is cold flow. I just wanna ask about the architect, is it okay if we use param of usecase is a Flow ?
g
I would say that such code smells, though nothing very bad with it
So in this case, I don’t wanna recollect the data flow (Socket) because it is cold flow.
If you don’t want to recollect it, you can convert it to hot flow with required strategy for retry cache
b
To convert it into hot flow you need coroutineScope to launch it, right ? Which scope you gonna pass in usecase ?
g
Correct, otherwise it will not be cancelled
Depends on your case, how long you want to cache it
assume it’s some kind repository class, you can have scope on the same level
It’s a good example when structured concurrency forces you to think about lifecycle If you would show some self-contained example, I could take a look For now I just don’t know how different parts are working and how you plan to use it
b
Is it good practice if I passing or inject coroutineScope in usecase or repository ?
g
Yes, otherwise it cannot work as repository to hold state
Of course it’s usually better to use it cold, if it possible, but it’s not always the case, so you need some scope on level of your app or level of particular repository
b
That make sense, thank you
I appreciate it
119 Views