Reputation: 4990
In my onViewCreated()
inside my MythFragment
I do these steps.
MutableLiveData<List<..>>
it.hasNext() == true
For some reason, only during the first run of the program, the it.hasNext()
gives me false
. I would expect it to be true, since the steps 1-3 should've already ensured, that the list is filled and the iterator points to the first element.
Interestingly, any later navigation on the MythView
retrieves the element correctly and it.hasNext()
gives me true
.
MythFragment.kt
class MythFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProviders.of(this).get(MythViewModel::class.java)
viewModel.populateMyths()
viewModel.fetchFromDatabase()
buttonNextMyth.setOnClickListener {
mythEvaluation.visibility = View.GONE
buttonIsThisMythTruthful.visibility = View.VISIBLE
viewModel.mythsIterator.let {
if (it.hasNext()) {
val myth = it.next()
mythText.text = myth.myth
mythEvaluation.text = myth.evaluation
} else {
Toast.makeText(activity, "There is no myth, because it.hasNext() is false!)", Toast.LENGTH_SHORT).show()
val action = MythFragmentDirections.actionMenuFragment()
Navigation.findNavController(view).navigate(action)
}
}
}
}
}
MythViewModel.kt
class MythViewModel(application: Application) : BaseViewModel(application) {
private val myths = MutableLiveData<List<Myth>>()
lateinit var mythsIterator: Iterator<Myth>
fun populateMyths() {
launch {
val dao = MythDatabase(getApplication()).mythDao()
if (dao.getRowCount() > 0)
return@launch
val mythList = arrayListOf(
Myth("This is the myth 1", "This is the evaluation of the myth 1"),
Myth("This is the myth 2", "This is the evaluation of the myth 2"),
Myth("This is the myth 3", "This is the evaluation of the myth 3"),
Myth("This is the myth 4", "This is the evaluation of the myth 4"),
Myth("This is the myth 5", "This is the evaluation of the myth 5")
)
dao.insertAll(
*mythList.toTypedArray()
)
}
}
fun fetchFromDatabase() {
launch {
val mythList = MythDatabase(getApplication()).mythDao().getAllMyths()
myths.value = mythList
myths.value?.let {
mythsIterator = it.iterator()
}
}
}
}
I believe the problem might be in the concurrency (Coroutines), but I don't understand what am I doing wrong.
Upvotes: 1
Views: 143
Reputation: 12305
As both functions populateMyths()
and fetchFromDatabase()
are launching new coroutines, both these coroutines will run in parallel. So the first time fetchFromDatabase()
is called, it may be retrieving the data before dao.insertAll()
has happened in populateMyths()
.
Maybe you should rethink / clarify what you aim to accomplish by launching these coroutines.
Upvotes: 2