'Store data and "Cannot create an instance of class ViewModel" - Hilt - Room - JetpackCompose
I try to store some days from ScheduleScreen
screen. Lib uses in theme topic.
While I was doing this, I had two questions:
why i got this error
Cannot create an instance of class com.example.ic.ScheduleScreenVM
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create
etc.and how i can store my days.
So my classes:
Create table for store days daysTable
:
@Entity()
data class DaysChoosenEntity(
var daysChoosen: Int,
@PrimaryKey(autoGenerate = true) var id: Int? = null
) {
}
Create requests in daysDAO
:
@Dao
interface DaysChoosenDAO {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertDays(days: DaysChoosenEntity)
@Delete
suspend fun deleteDays(days: DaysChoosenEntity)
@Query("SELECT * FROM dayschoosenentity")
fun getDays(): Flow<List<DaysChoosenEntity>>
}
Create DB and put top two into daysDB
:
@Database(
entities = [DaysChoosenEntity::class],
version = 1
)
abstract class DaysChoosenDB: RoomDatabase() {
abstract val daysChoosenDAO: DaysChoosenDAO
companion object {
const val DATABASE_NAME = "dayschoosen_db"
}
}
I don't fully understand its purpose, but daysRepo
:
class DaysChoosenRepositoryImpl(
private val dao: DaysChoosenDAO
): DaysChoosenRepository {
override fun getDaysChoosen(): Flow<List<DaysChoosenEntity>> {
return dao.getDays()
}
override suspend fun insertDaysChoosen(days: DaysChoosenEntity) {
dao.insertDays(days)
}
override suspend fun deleteDaysChoosen(days: DaysChoosenEntity) {
dao.deleteDays(days)
}
}
So i create calss who store all ma UseCases daysUseCases
:
data class DaysChoosenUseCase (
val getDaysChoosen: GetDaysChoosen,
val deleteDaysChoosen: DeleteDaysChoosen,
val addDaysChoosen: AddDaysChoosen
)
at first i would just like to learn how to add days. so addDaysChoosen
UseCase:
class AddDaysChoosen( //Another question - do i need to @Inject constructor
private val repository: DaysChoosenRepository
) {
suspend operator fun invoke(days: DaysChoosenEntity){
repository.insertDaysChoosen(days)
}
}
Now i try to provide this all in appModule
:
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun provideDaysChoosenDB(app: Application): DaysChoosenDB{
return Room.databaseBuilder(
app,
DaysChoosenDB::class.java,
DaysChoosenDB.DATABASE_NAME
).build()
}
@Provides
@Singleton
fun provideDaysChoosenRepository(db: DaysChoosenDB): DaysChoosenRepository{
return DaysChoosenRepositoryImpl(db.daysChoosenDAO)
}
@Provides
@Singleton
fun provideDaysChoosenUseCase(repository: DaysChoosenRepository): DaysChoosenUseCase{
return DaysChoosenUseCase(
getDaysChoosen = GetDaysChoosen(repository),
deleteDaysChoosen = DeleteDaysChoosen(repository),
addDaysChoosen = AddDaysChoosen(repository)
)
}
Now lets look on my ScheduleScreenVM
:
(I've seen people create a separate class with states and a class with events. but I don't fully understand how to use it. so everything is inside a single vm)
@HiltViewModel
class ScheduleScreenVM @Inject constructor (
private val daysChoosenUseCase: DaysChoosenUseCase
): ViewModel() {
//states
var daysChoosen by mutableStateOf(mutableListOf(0,0,0,0,0,0,0))
var rememem by mutableStateOf(
SnapshotStateList<Boolean>().also {
for(day in 0..6){
it.add(false)
}
}
)
//events
fun snapChanged(int: Int){ rememem[int] = !rememem[int] }
fun insertDays(int: Int) = viewModelScope.launch {
daysChoosenUseCase.addDaysChoosen(
DaysChoosenEntity(daysChoosen = int)
)
}
fun getMyDays() {
daysChoosenUseCase.getDaysChoosen
}
}
This is where a little difficulty begins. To add a day to the database I have to use the insertDays
function from the VM. for example
DaysOfWeekButton(
onClick =
{
viewModel.snapChanged(day)
if(viewModel.rememem[day]) {
viewModel.daysChoosen.set(day, 1)
viewModel.insertDays(1) //hmmm.... like this?
}
else {
viewModel.daysChoosen.set(day, 0)
viewModel.insertDays(0) //hmmm.... like this?
}
},
I want to show the result like this (probably)
Text("${viewModel.getMyDays}")
Something like this. I ended up getting an error (beginning of a topic). And I didn’t fully understand how writing to the database is done using the VM. Rly thank you for reading.
UPD. build gradle
// Compose dependencies
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.4.1"
implementation "androidx.navigation:navigation-compose:2.4.1"
implementation "androidx.compose.material:material-icons-extended:$compose_version"
// Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0'
//Dagger - Hilt
implementation "com.google.dagger:hilt-android:2.41"
kapt "com.google.dagger:hilt-android-compiler:2.41"
kapt "androidx.hilt:hilt-compiler:1.0.0"
// Room
implementation "androidx.room:room-runtime:2.4.2"
kapt "androidx.room:room-compiler:2.4.2"
// Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:2.4.2"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.1"
//implementation 'androidx.core:core-ktx:1.7.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1'
implementation 'androidx.activity:activity-compose:1.4.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
Solution 1:[1]
In this function you don't return anything:
fun getMyDays() {
daysChoosenUseCase.getDaysChoosen
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | mojtaba mohammadian |