I know this question has been asked a couple of times, but I have a funny situation here that I can't figure out.
I have a database
with "TASKS" and, apart from the writing/updating methods, I'm calling the get method twice: one for getting the last created task, and another to select an specific task by ID
@Query("SELECT * FROM tasks_history_table ORDER BY taskId DESC LIMIT 1")
suspend fun getCurrentTask(): Task2?
@Query("SELECT * from tasks_history_table WHERE taskId = :key ")
suspend fun get(key: Long): Task2?
Then in the viewModel
I'm launching a coroutine
for each time I call one of these methods.
This one for the last created Task:
private fun initializeCurrentTask(){
viewModelScope.launch {
_currentTask.value = getCurrentTaskFromDatabase()!!
}
}
suspend fun getCurrentTaskFromDatabase(): Task2? {
var currentTask = database.getCurrentTask()
return currentTask
}
And this one for the specific task
fun initializeSelectedTask(){
viewModelScope.launch {
_currentTask.value = getSelectedTaskFromDatabase(selectedTaskId.value!!)!!
}
}
suspend fun getSelectedTaskFromDatabase(taskId: Long): Task2? {
var currentTask = database.get(selectedTaskId.value!!)!!
return currentTask
}
So they are both pretty much the same, except for the parameter Id passed.
Then, I'm sending that data to the Fragment
to update the UI, via LiveData
private val _currentTask = MutableLiveData<Task2>()
val currentTask : LiveData<Task2>
get() = _currentTask
And here the observer
:
timerViewModel.currentTask.observe(viewLifecycleOwner) {
updateUIText()
updateCountdownUI()
updateAnimation()
}
Everytime I call the function to get the las saved task, the observers
are called and everything works fine. But whenever I call the function to get a specific task by Id, the observers
are not called.
I've set Logs
all around and I've reached the conclusion that the LiveData
is getting updated, but the observer
is not triggered.
Here's the repo in case someone can have it a look. Thanks!! https://github.com/arieldipietro/PomodoroTechnique
CodePudding user response:
In FragmentTimer
and FragmentHistory
, you have created viewModel
instances using their respective fragments
as owners, which makes them to observe liveData
which are triggered by their instances only. So, now when you trigger a task from FragmentHistory
it isn't get observed in FragmentTimer
.
You need to use SharedViewModel
for passing data between fragments, you have to create object of TimerViewModel
using activity
as its owner, then you would be able to observe from FragmentTimer
. Pass requireActivity()
as the owner in ViewModelProvider
's constructor.
timerViewModel = ViewModelProvider(requireActivity(), viewModelFactory)[TimerViewModel::class.java]
You can read more about it in this codelab tutorial.