I am having issues with a query which includes BEGINSWITH (or CONTAINS for that matter). I am trying to follow the example as found in the Mongo Db documentation:
This query to find instances of the <Pantry> model is not filtering the way it should.
(all of this is in the viewModel)
This is the query:
val searchResults = realm
.query<Pantry>("itemName BEGINSWITH $0", searchText.value)
.find()
.asFlow()
.map { results ->
results.list.toList()
}
.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(),
emptyList()
)
searchText is a String with a search pattern input by the user to find instances of the Pantry model. This done by use of a TextField.
'realm' is defined like this: private val realm = MyApp.realm.
MyApp is :
class MyApp: Application() {
companion object {
lateinit var realm: Realm
}
override fun onCreate() {
super.onCreate()
realm = Realm.open(
configuration = RealmConfiguration.create(
schema = setOf(
Pantry::class,
Department::class,
Market::class,
)
)
)
}
}
I implemented this function to see what was happening; if the query was doing anything or not:
suspend fun checkSearchResults(){
searchResults.collect { results ->
if (results.isEmpty()) {
Log.d("Search", "No search results found")
} else {
// Loop through or access items in results
for (item in results) {
Log.d("Search", "Found item: ${item.itemName}")
}
}
}
}
This is the log as the user inputs characters:
The value of searchText: h
D Found item: bananas
D Found item: clorox
D Found item: garbanzos
D Found item: ham
D Found item: laundry detergent, pods
D Found item: milk
D Found item: olives
D Found item: pastries
D Found item: salmon
D Found item: water, sparkling
D The value of searchText: ha
D Found item: bananas
D Found item: clorox
D Found item: garbanzos
D Found item: ham
D Found item: laundry detergent, pods
D Found item: milk
D Found item: olives
D Found item: pastries
D Found item: salmon
D Found item: water, sparkling
D The value of searchText: ham
D Found item: bananas
D Found item: clorox
D Found item: garbanzos
D Found item: ham
D Found item: laundry detergent, pods
D Found item: milk
D Found item: olives
D Found item: pastries
D Found item: salmon
D Found item: water, sparkling
which is the entire database.
So, from the log its evident that the query is ignoring the filter and all instances are included.
Can anyone point out where I am failing? I think I'm following the documentation pretty closely.
UPDATE:
if I use a query like this:
.query<Pantry>("itemName = $0", searchText.value) and using a known itemName, the result is an empty list.
UPDATE 2:
searchResults does not update. My understanding was that because it's a StateFlow it would update each time the conditions change (searchtext.value), but its not happening.
This was the issue: the value of
searchResultswas not updating, therefore even though thetextFieldwas issuing characters to thesearchText variable, nothing was happening.The solution: force an update on the variable
searchResults. This was accomplished by enclosing the code forsearchResultsin a function and calling the function from theonValueChangein thetextField.Complications: My understanding is that just because a function is called, doesn't necessarily generate an update on a
StateFlowentity, so by enclosing it in a .collect can make that happen. Complications betweenviewModeland theComposableand the use of var and val in the declaration ofvariables.So to solve for said complications, I declared the following:
1 for use in the viewModel and the other for the Composable.
and this is the function:
it needs to be in a
suspend function, due to the.collect.So the function is called from the
textField:It works pretty well. Tested it CONTAINS and with BEGINSWITH and both work.