I have a AndroidViewModel for one of my fragments which contains a LiveData List, and I have another property for selected item of another LiveData List. Below is an example of what I am talking about:
class TeamViewModel(app: Application): AndroidViewMode(app) {
...
val selectedTeam = MutableLiveData<Team>()
val allTeams: LiveData<List<Team>>
get() = repository.getAllTeams().toLiveData()
val allPlayers: LiveData<List<Player>>
get() = repository.getAllPlayers().toLiveData()
...
}
Note: getAllTeams
and getAllPlayers
returns a RxJava Flowable List, which I then convert to LiveData List via .toLiveData
Currently, allPlayers
represents all the players from all teams. I'd like to make it so that whenever the value of selectedTeam
changes, that allPlayers
gets filtered down to only display players from the selectedTeam
.
What I've tried is to filter allPlayers
directly like so:
val allPlayers: LiveData<List<Player>>
get() = repository.getAllPlayers()
.flatMap { list -> Flowable.fromIterable(list)
.filter {
player -> player.team == selectedTeam.value?.team
}
}
.toList()
.toFlowable()
.toLiveData()
But as you may or may not guess, it doesn't update the filter for allPlayers
whenever selectedTeam
changes.
Is there anyway to dynamically change the filter for allPlayers
whenever selectedTeam
changes?
EDIT
Thanks to @EpicPandaForce, the final solution I came up with is as followed:
I created this extension method:
fun <T, R> LiveData<T>.switchMap(func: (T) -> LiveData<R>) = Transformations.switchMap(this, func)
to make the code more readable.
I've also created a function in my repository called getAllPlayersFromTeam(team: Team)
which, as the function specifies, gets all the players from a team.
Finally this is the end result of my property:
val allPlayersFromSelectedTeam: LiveData<List<Player>>
get() = selectedTeam.switchMap {
repository
.getAllPlayersFromTeam(it)
.toLiveData()
}
You need to switchMap
over the selectedTeam
, and possibly renamed "allPlayers" because that's a lie. :P
val selectedTeam = MutableLiveData<Team>()
val allTeams: LiveData<List<Team>>
get() = repository.getAllTeams().toLiveData()
val playersOfSelectedTeam: LiveData<List<Player>>
get() = Transformations.switchMap(selectedTeam) { team ->
val allPlayers = repository.getAllPlayers().toLiveData()
val players = when {
team == null -> allPlayers
else -> {
Transformations.switchMap(allPlayers) { playerList ->
val filteredPlayers = MutableLiveData<List<Player>>()
val filteredList = playerList.filter { player -> player.team == team }
filteredPlayers.value = filteredList
filteredPlayers
}
}
}
players
}
Which I really hope it works as I wrote it here directly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With