I want to load a long list inside my ViewModel class, queried from database. Data will then be shown using LazyColumn. When loading in IO Dispatcher using kotlin coroutine it throws exception but no problem when loading in Main Dispatcher.
ViewModel Class:
class TestViewModel: ViewModel() {
val itemList = mutableStateListOf<TestModel>()
init {
viewModelScope.launch(Dispatchers.IO){
loadList()
}
}
Error Message:
E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
Process: in.rachika.composetest2, PID: 19469
java.lang.IllegalStateException: Reading a state that was created after the snapshot was taken or in a snapshot that has not yet been applied
at androidx.compose.runtime.snapshots.SnapshotKt.readError(Snapshot.kt:1518)
at androidx.compose.runtime.snapshots.SnapshotKt.current(Snapshot.kt:1758)
at androidx.compose.runtime.snapshots.SnapshotStateList.add(SnapshotStateList.kt:374)
at in.rachika.composetest2.Tests.ViewModel.TestViewModel.loadList(TestViewModel.kt:24)
at in.rachika.composetest2.Tests.ViewModel.TestViewModel.access$loadList(TestViewModel.kt:13)
at in.rachika.composetest2.Tests.ViewModel.TestViewModel$1.invokeSuspend(TestViewModel.kt:19)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
Snapshots are transactional and run on ui thread. You are attempting to create a snapshot on the IO thread. If you want to do your data loading on the IO thread, you need to switch back to the UI thread after you've retrieved the data. Example:
class MyViewModel: ViewModel() {
fun getData() {
viewModelScope.launch(Dispatchers.IO) {
// Get Data
val data = someAPI.getData()
withContext(Dispatchers.Main) {
// Display the data...
displayData(data)
}
}
}
}
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