I have a LiveData object (_tracklist) that is making a call to the Dao and retrieves tracks by the songId argument from RoomDB and store it in the List. The new track with the new songID is inserted to the database successfully and the LiveData observer is triggered in the fragment, but the database call is always with the initial argument value even if the value changes in runtime (songId). How can I trigger the call with the updated value?
The methods run in the following order: createNewSong(), recordTrack()
private var songID:Long = 0
private val _trackList: LiveData<List<Track>> = db.trackDao().getTracksBySongId(songID)
val trackList: LiveData<List<Track>>
get() = _trackList
suspend fun createNewSong(){
val newSong = Song(0, null, true, "Song ${songList.value?.size?.plus(1)}")
val job = viewModelScope.async() {
db.songDao().insert(newSong)
}
songID = job.await() //The song ID is changed here
}
fun recordTrack(name: String, pcmDir: String, wavDir: String) {
val newTrack = Track(
0,
true,
name,
pcmDir,
wavDir,
TypeConverter.dateToTimestamp(Date()),
null,
null,
songID,
""
)
AudioController.lastRecorded = newTrack
viewModelScope.launch {
insertTrackToDb(newTrack)
}
}
interface TrackDao{
@Query("SELECT * FROM tracks WHERE songID = :id")
fun getTracksBySongId(id:Long):LiveData<List<Track>>
}
//OBSERVER
val trackListObserver = Observer<List<Track>> {
adapter.submitList(viewModel.trackList.value)
}
viewModel.trackList.observe(viewLifecycleOwner, trackListObserver)
Basically I need to call
private val _trackList: LiveData<List<Track>> = db.trackDao().getTracksBySongId(songID)
each time when the argument songID is changed and new Track with the new songID value is inserted to the database.
The issue was solved by using Transformations.switchMap
private var songID: MutableLiveData<Long> = MutableLiveData(0)
private var _trackList: LiveData<List<Track>> = Transformations.switchMap(songID)
{ id ->
db.trackDao().getTracksBySongId(id)
}