Reputation: 91
Im triying implement a reactive search function for my first App in Meteor using Meteor:Search-source package. The search function is working fine. I have a input text search field, and 2 list. The first part called "search result" get the items found when we search for some word (for example try with london), and the second part get all items in my Collection. These items are linked to a reactive helper/template function. The reactivity when I get all items is working fine if I voteUp or Down. I can see in realtime how it is updated. But when I want upvote or downvote some item found in my search, upvote and downvote is not updating, is like the items found, lost the reactivity (I can see that if I upvote or downvote in some item in the first section ("search results") the items in second list (all items) is updating right....
this is my App My App
You can check it out the issue key in "london" in search field and upvote or downvote to see that in second list the item is correctly updated, but is not working if you upvote or downvote in "search result" section (no reactive).
CLIENT
// helper function
Template.searchResult.helpers({
getItems: function() {
return itemSearch.getData({
transform: function(matchText, regExp) {
return matchText.replace(regExp, "$&")
},
sort: {upvote: -1}
});
},
isLoading: function() {
return itemSearch.getStatus().loading;
}
});
//This line return all documents by default (when empty searchbox text is empty)
Template.searchResult.rendered = function() {
itemSearch.search('');
};
SERVER
SearchSource.defineSource('items', function(searchText, options) {
var options = {sort: {upvote: -1}, limit: 20};
// var options = options || {};
if(searchText) {
var regExp = buildRegExp(searchText);
/*var selector = {title: regExp, description: regExp};*/
var selector = {$or: [
{title: regExp},
{description: regExp}
]};
return Websites.find(selector, options).fetch();
} else {
return Websites.find({}, options).fetch();
}
});
function buildRegExp(searchText) {
var words = searchText.trim().split(/[ \-\:]+/);
var exps = _.map(words, function(word) {
return "(?=.*" + word + ")";
});
var fullExp = exps.join('') + ".+";
return new RegExp(fullExp, "i");
}
HTML
<!-- template that displays searched website items -->
<template name="searchResult">
<div class="container">
<div class="jumbotron">
<h3> Search results </h3>
<ol>
{{#each getItems}}
{{> website_item}}
{{/each}}
</ol>
</div>
</div>
<!-- template that displays individual website entries -->
<template name="website_item">
<li>
<a href="{{url}}">{{title}}</a>
<p>
{{description}}
</p>
<a href="#" class="btn btn-default js-upvote">
<span class="glyphicon glyphicon-arrow-up" aria-hidden="true"> </span>
</a>
<a href="#" class="btn btn-success">
{{upvote}}
</a>
<a href="#" class="btn btn-default js-downvote">
<span class="glyphicon glyphicon-arrow-down" aria-hidden="true"></span>
</a>
<a href="#" class="btn btn-danger">
{{downvote}}
</a>
<p>
Created On: {{createdOn}}
</p>
<a href="/details/{{_id}}" class="btn btn-success js-description">
view web description
</a>
<!-- you will be putting your up and down vote buttons in here! -->
</li>
Some suggestion?? Many thanks in advance!
Upvotes: 2
Views: 282
Reputation: 16488
The returned data records themselves are not reactive, as the data is fetched internally using a method call (search.source
).
You get a snapshot of the data as it was when you searched.
In addition, the data is cached by default, so subsequent searches for the same term don't trigger requests to the server for a certain period of time. You can adjust the time period via the keepHistory
option.
Therefore, you will not get reactive changes via the package and it does not seem like an adequate solution for your situation.
You could try and get the data via a subscription and map the data returned from the search to the records in your collection but that seems to be costly.
Also, see this issue, which demonstrates that others had encountered the same type of issue.
Upvotes: 2