Reputation: 61
I'm new with Room Database and I would like to extract from one database an array of int. I think that the problem is in the code of the fragment, when I would like to use the function "stationlist" to obtain an array of the codes of stations present in database. The output "StationList" seems to be Unit instead of Array: does anyone know the solution? Thank you
This is my entity and data class:
@Parcelize
@Entity(tableName = "user_table")
data class User(
@PrimaryKey(autoGenerate = true)
val id: Int,
val Name: String,
val StationCode: Int
): Parcelable
This is my Dao:
@Dao
interface UserDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun addUser(user: User)
@Query("SELECT intArrayOf(StationCode) FROM user_table")
suspend fun stationlist() : Array
}
This is my database:
@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class UserDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
companion object {
@Volatile
private var INSTANCE: UserDatabase? = null
fun getDatabase(context: Context): UserDatabase{
val tempInstance = INSTANCE
if(tempInstance != null){
return tempInstance
}
synchronized(this){
val instance = Room.databaseBuilder(
context.applicationContext,
UserDatabase::class.java,
"user_database"
).build()
INSTANCE = instance
return instance
}
}
}
}
This is my Repository:
class UserRepository(private val userDao: UserDao) {
val readAllData: LiveData<List<User>> = userDao.readAllData()
suspend fun addUser(user: User){
userDao.addUser(user)
}
suspend fun stationlist(){
userDao.stationlist()
}
}
and this is my Viewmodel:
class UserViewModel(application: Application): AndroidViewModel(application) {
val readAllData: LiveData<List<User>>
private val repository: UserRepository
init {
val userDao = UserDatabase.getDatabase(
application
).userDao()
repository = UserRepository(userDao)
readAllData = repository.readAllData
}
fun addUser(user: User){
viewModelScope.launch(Dispatchers.IO) {
repository.addUser(user)
}
}
fun stationlist(){
viewModelScope.launch(Dispatchers.IO) {
repository.stationlist()
}
}
}
At last this is a part of the fragment:
class AddFragment : Fragment(), OnMapReadyCallback {
private lateinit var mUserViewModel: UserViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// here is all the part regarding displaying the layout and collecting data
mUserViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
view.add_btn.setOnClickListener {
insertDataToDatabase()
}
return view
}
private fun insertDataToDatabase() {
if(inputCheck(name, stationcode)){
val user = User(
0,
name,
stationcode)
mUserViewModel.addUser(user)
// Here is the problem:
val StationList= mUserViewModel.stationlist()
}
Upvotes: 0
Views: 756
Reputation: 154
The problem is the dao method. Change it with this:
@Query("SELECT StationCode FROM user_table")
suspend fun stationlist() : Array<Int>
EDIT
There are some other problems with coroutines. In fragment you call this:
val StationList= mUserViewModel.stationlist()
But this method does not return immediately.
fun stationlist(){
viewModelScope.launch(Dispatchers.IO) {
repository.stationlist()
}
}
You should implement a live data array, which is updated when async db query returns. In this way:
val stationList: MutableLiveData<Array<Int>>() = MutableLiveData()
fun stationlist(){
viewModelScope.launch(Dispatchers.IO) {
stationList.value = repository.stationlist()
}
}
And in fragment you have to observe the list:
mUserViewModel.stationList.observe(viewLifecycleOwner) { array ->
// do stuff
}
You also have to change repository stationlist()
return type:
suspend fun stationlist(): Array<Int> {
return userDao.stationlist()
}
These are useful links to understand coroutines, room and livedata:
Upvotes: 2