Reputation: 716
I'm trying to retrieve a single object from my room database given its title but when I get to the fragment where I want this to happen, I have no way to access the object's fields. The method I'm trying to use is retrieveMovie but the observer shows that it = List! and for some reason I cannot get the movie given its title and then get its fields to bind them to my view. How can I do this?
I tried accessing the movie with it's index(0) but the second movie I click on causes an app crash that returns: 'java.lang.IndexOutOfBoundsException: Index: 0, Size: 0'
This is the fragment's part:
if(arguments != null){
val titleString = arguments?.getString("Title")
//observe viewmodel
if (titleString != null) {
mMoviesViewModel.retrieveMovie(titleString).observe(viewLifecycleOwner, Observer { movie ->
itemTextTitle.text = movie.title //this doesn't work
})
}
} else {
//display error message if arguments are null
Toast.makeText(context, "Error loading content", Toast.LENGTH_SHORT).show()
}
This is the db's viewmodel:
class MoviesViewModel(application: Application): AndroidViewModel(application) {
val readAllData: LiveData<List<Movies>>
private val repository: MoviesRepository
init {
val moviesDao = MoviesDatabase.getDatabase(application).moviesDao()
repository = MoviesRepository(moviesDao)
readAllData = repository.readAllData
}
fun addMovie(movie: Movies) {
viewModelScope.launch(Dispatchers.IO) {
repository.addMovie(movie)
}
}
fun movieExists(id: Int): Boolean{
viewModelScope.launch(Dispatchers.IO){
repository.movieExists(id)
}
return true
}
fun retrieveMovie(title: String): LiveData<List<Movies>> {
return repository.retrieveMovie(title)
}
}
This is the db's repository:
class MoviesRepository (private val moviesDao: MoviesDao) {
val readAllData: LiveData<List<Movies>> = moviesDao.readALlData()
fun addMovie(movie: Movies){
moviesDao.addMovie(movie)
}
fun movieExists(id:Int){
moviesDao.movieExists(id)
}
fun retrieveMovie(title:String): LiveData<List<Movies>> {
return moviesDao.retrieveMovie(title)
}
}
Dao:
package com.app.challengemovieapp.db
import androidx.lifecycle.LiveData
import androidx.room.*
import com.app.challengemovieapp.model.Movie
import kotlinx.coroutines.flow.Flow
@Dao
interface MoviesDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun addMovie(movie:Movies)
@Query("SELECT * FROM movie_table ORDER BY id ASC")
fun readALlData(): LiveData<List<Movies>>
@Query("SELECT EXISTS(SELECT * FROM movie_table WHERE id = :id)")
fun movieExists(id : Int) : Boolean
@Query("SELECT * FROM movie_table WHERE title = :title")
fun retrieveMovie(title:String): LiveData<List<Movies>>
}
Upvotes: 1
Views: 3221
Reputation: 892
To get a single entity you can use limit. Here is an example
@Query("SELECT * FROM movie_table WHERE title = :title LIMIT 1")
fun retrieveMovie(title:String): LiveData<Movies>
Upvotes: 2
Reputation: 177
so the reason why you can't access the Movie object is cause you are mentioning this.
@Query("SELECT * FROM movie_table WHERE title = :title")
fun retrieveMovie(title:String): LiveData<List<Movies>>.
So LiveData is returning a List of Movie objects.
what you can do is
it.get(0).getTitle()
It should work.
Upvotes: 0