All,
I’m trying to build a simple search on text list.
The filtered resultset gives write number of rows but incorrect data rows.
Any help is greatly appreciated. Thanks
Sample code:
import Program from './Program.svelte';
import { ProgramsCollection } from '../api/ProgramsCollection';
let programs = [];
let filter = {};
let search = '';
$m: programs = ProgramsCollection.find(filter).fetch();
const handleSubmit = () => {
if (search != '') {
filter = { title: new RegExp(search, 'i') };
} else {
filter = {};
}
};
<div class="panel">
<input class="program-title" type="text" name="search" placeholder="Type to search programs" bind:value={search} />
<button on:click={() => handleSubmit()}>Filter Now </button>
</div>
{#each programs as program, i}
<Program {program} />
{/each}
Can you give us an example of your output? By “right amount but incorrect” you mean that there are eg. 4 programs but the search string is not applied correctly?
Of course you need to subscribe, but I assume you either have a global subscription or the autopublish package installed. If the collection is big, you should reimplement the current solution in a more efficient way, but that does not answer your question now.
You don’t need a text index as the filtering is happening locally at the moment. And as for the database, the regex search works fine, but is generally slow (again, it depends on the collection size).
You can try to display the filter value on the page. I remember having issues that the regex had been considered the same although the string inside has changed. I don’t know what was the exact situation though. You can also doublecheck that the programs var does get recalculated:
In your Meteor.subscribe use text instead of filter. The way you structured your publication function, it looks like it expects the searchValue to be a simple string not an object.
I made the changes as suggested. Now I don’t see any results.
What do I put in for filter below? I only want to get data collection when I click Submit.
let text = '';
let searchText ='';
let filter = {};
let programs;
$m: {
const handler = Meteor.subscribe('programs', searchText);
isLoading = !handler.ready();
programs = ProgramsCollection.find(filter).fetch();
console.log('filter', filter);
console.log('programs', programs);
}
const handleSubmit = (e) => {
console.log('text', text);
searchText = text;
if (!text) {
filter = {};
} else {
filter = { title: new RegExp(text, 'i') };
}
};
When I make search ‘Show’ it returns 2 program records. 3 calls r made. But data is correct.
Console.logs
filter - {title:/Show/i}
programs -
filter - {title:/Show/i}
programs - [2] records
filter - {title:/Show/i}
programs - [2] records
again if search for ‘Program’, i get correct data but calls are 3.
I have changed the code to fire only when I click button. The program is making multiple calls.
I’m just trying to write very basic search functionality here.
Ok then I suggest you change your publication function to accept a filter object as the argument and change your Meteor.subscribe to pass in the filter object as you had it before.
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
import { ProgramsCollection } from '../api/ProgramsCollection';
Meteor.publish('programs', function (filter={}) {
// you'll need to check the arguments assuming you don't have the insecure package installed for prototyping only
// this is a quick and dirty check, you'll want to check them more robustly
check(filter, Object);
return ProgramsCollection.find(filter);
});
Thanks so much. It’s giving the expected results. See only one call to subscription call…
But I see 3 log messages when I console.log(‘programs’, programs)
I see right count of rows in collection and right data but UI does not refresh to show it sometimes. If I change the search criteria where number of rows change then UI refreshes.