I am using Flow to fetch a list of some objects fr...
# android
s
I am using Flow to fetch a list of some objects from the API. I collect in the ViewModel inside a viewModelScope which is then pushed to the UI via a LiveData. I am also supposed to filter this list based on a query. Should I filter at the flow level in the repository or should I filter in the ViewModel once it has been collected and let filtering be part of LiveData instead of flow.
m
Add filter in viewmodel its good option.
s
Do you mean filter after collecting it from the Flow object?
y
If you have a
Flow<List<T>>
you can just use
map
to apply a filter on the list. However, if you are collecting it in the ViewModel itself, you can simply filter it after collection - before assigning to LiveData.
If you have a
Flow<T>
instead, you can even call filter directly on it
r
flow.filter {}.asLiveData
Filter in the flow level and just do asLiveData in the viewmodel
s
I am collecting the data in the ViewModel so when the flow object is built in the repository there is no data to filter on. The data is fetched when it is collected in the ViewModel. Main question is how to filter locally using Flow when data will be fetched from Retrofit in the ViewModel or if that should be done using LiveData and not in flow. https://github.com/sudhirkhanger/NetworkSample Repository
Copy code
fun getCountries(): Flow<CountriesResponse> = flow { emit(networkSampleService.countries()) }
ViewModel
Copy code
private fun fetchCountries() {
        viewModelScope.launch {
            repository.getCountries()
                .onStart { _countriesViewEffects.postValue(Event(Resource.loading(null))) }
                .catch { _countriesViewEffects.postValue(Event(Resource.error(it.message ?: "", null))) }
                .collect {
                    it.data?.let { list -> countries.addAll(list) }
                    _countriesLiveData.postValue(Resource.success(it))
                }
        }
    }
I guess thing for me will be to collect the data in the repository itself. Then I can manipulate it as I would like to. This will also make sure that the data is there as long as the repository is alive. Otherwise the data will be downloaded over and over whenever the user visits that particular fragment.
r
If your just making one network call you dont need a flow. Flow is more for streams of data. Its abit of overkill for one shot api calls. you can just use a suspend function
Copy code
suspend fun countries() { networkSampleService.countries()}
than in your view model just use a liveData builder
Copy code
val countriesLiveData = liveData { emit (Event(Resource.loading(null))) ... emit (Event(Resource.Success(it)) }
and you can do whatever logic you want in the live data builder before emitting the values