Reputation: 85
I do not know how to implement a filter query properly inside the Repository and the ViewModel to use it to display the filtered string in a Textview or anything else really. My Entity, Dao, Repository, and ViewModel are as follows:
User.kt
@Entity(tableName = "user_data")
data class User (
@PrimaryKey(autoGenerate = true) val id: Int,
@ColumnInfo(name = "name") val name: String
)
UserDao.kt
@Dao
interface UserDao {
@Insert
fun addUser(user: User)
@Query("SELECT name FROM user_data WHERE name LIKE :filter LIMIT 1")
fun getFilteredUser(filter: String): LiveData<String>
}
UserRepository.kt
class UserRepository(private val userDao: UserDao) {
fun addUser(user: User) { userDao.addUser(User) }
fun getFilteredUser(filter: String) {userDao.getFilteredUser(filter)}
}
UserViewModel.kt
class UserViewModel(application: Application): AndroidViewModel(application) {
private val repository: UserRepository
init {
val userDao = UserDatabase.getDatabase(application).userDao()
repository = UserRepository(userDao )
}
fun addUser(user: User) {
viewModelScope.launch(Dispatchers.IO){
repository.addUser(user)
}
}
fun getFilteredUser(filter: String){
return repository.getFilteredUser(filter)
}
}
How would I proceed from here to make it possible to e.g. display the filtered User String in a textview or anything like that and how do I write the method correctly inside the repository and the viewmodel? Thank you for your help!
Upvotes: 1
Views: 1253
Reputation: 356
Easiest way I have found :
1 - In your DAO interface, add a parameter for the SQL query you want to use. For example:
@Dao
interface CrPairsDao {
@Query("SELECT * FROM CrPairsModel WHERE columnName = :queryParam")
fun getCrPairs(queryParam: String): Flow<List<CrPairsModel>>
}
In this example, columnName represents the column name in the table where you want to apply the query condition, and queryParam is the parameter for the query.
2 - Update your repository to pass the parameter value to the DAO method. Here's an example:
class CrPairsRepository(private val crPairsDao: CrPairsDao) {
fun getCrPairsWithQuery(queryParam: String): Flow<List<CrPairsModel>> {
return crPairsDao.getCrPairs(queryParam)
}
}
In this example, the getCrPairsWithQuery function in the repository accepts the queryParam parameter and directly calls the DAO's getCrPairs method with the parameter value.
3 - Finally, in your ViewModel, update the function that fetches the data to include the parameter value. Here's an example:
class CrPairsViewModel(private val crPairsRepository: CrPairsRepository) : ViewModel() {
private val _crPairsLiveData = MutableLiveData<List<CrPairsModel>>()
val crPairsLiveData: LiveData<List<CrPairsModel>> = _crPairsLiveData
fun fetchCrPairsWithQuery(queryParam: String) {
viewModelScope.launch {
crPairsRepository.getCrPairsWithQuery(queryParam).collect {
_crPairsLiveData.value = it
}
}
}
}
In this example, the fetchCrPairsWithQuery function in the ViewModel triggers the repository's getCrPairsWithQuery function with the provided query parameter. The resulting Flow is collected using collect, and the emitted value is set to the crPairsLiveData using the _crPairsLiveData.value.
With these changes, you can now pass a parameter to the SQL query in the DAO method and retrieve the filtered Flow<List> in your ViewModel with crPairsLiveData.observeAsState() and .value?.let
Upvotes: 0
Reputation: 1596
Try the following
UserDao
change getFilteredUser
as follows
@Query("SELECT name FROM user_data WHERE name LIKE '%' || :filter || '%' LIMIT 1")
fun getFilteredUser(filter: String): Stringl̥
UserRepo
use coroutines to perform the database I/O operations
suspend fun addUser(user: User) {
withContext(Dispatchers.IO) {
userDao.addUser(user)
}
}
suspend fun getFilteredUser(filter: String): String {
return withContext(Dispatchers.IO) {
userDao.getFilteredUser(filter)
}
}
ViewModel
fun addUser(user: User) {
viewModelScope.launch {
repository.addUser(user)
}
}
private val _dataToUi = MutableLiveData<String>()
val dataToUi: LiveData<String>
get() = _dataToUi
suspend fun getFilteredUser(filter: String): String? {
return withContext(Dispatchers.IO) {
repository.getFilteredUser(filter)
}
}
// to set the filterquery from the fragment/activity
fun setFliterQuery(query: String) {
viewModelScope.launch {
_dataToUi.value = getFilteredUser(query)
}
}
Activity
binding.button.setOnClickListener {
val queryKey = binding.queryKey.text.toString()
Log.i("activity", queryKey)
userViewModel.setFliterQuery(queryKey)
}
userViewModel.dataToUi.observe(this) { result ->
result?.apply {
Log.i("activity", result)
binding.resultText.text = result
}
}
Upvotes: 3