Emo
Emo

Reputation: 620

Search with the URL Query Parameters on Flow Router

I use Search Source, and Flow Router from Arunoda. They both work great, but I'm just struggling to get them work together.

I have a helper that returns some documents rendered from the server-run SearchSource method like this:

Template.search.helpers({
  things: function() {
    var currentUserId = Meteor.userId();
    var langParam = FlowRouter.current().queryParams.lang;
    console.log(langParam);
    return BookSearch.getData({
      sort: {date_added: -1}
    });
  }
});

As you see, I'm just trying to search for things that are registered in the language entered at the URL (e.g. 'en') as a query parameter. Let's say in "english" as in this example:

http://localhost:3000/search?lang=en

I can perfectly read the "en" and log on the console by the below code, but it does not work to search with. I mean because of this code:

var langParam = FlowRouter.current().queryParams.lang;
console.log(langParam);

I get "en" printed on the browser console. But I don't get the things that are registered in "en" language.

So how can I achieve a proper search using the query parameters?

What I need to know is how to enter in the helper to render only data that fetches to the condition I want (in this case, english language - {lang: langParam}. For that one uses the Package.getData() API, but I could not locate exactly how.

Upvotes: 2

Views: 972

Answers (1)

Serkan Durusoy
Serkan Durusoy

Reputation: 5472

First of all, searchsource sets up necessary data delivery for you so you don't have to, indeed should not set up publications or subscriptions for your search flow. There's tons of literature around for how pub/sub works in Meteor so I'll skip ahead to your searchsource problem.

I see that you want to scope your search to a certain language. Here's a basic set up that would get you going. You should also fine tune things like throttling, metadata handling, limiting, paging, input and query param sanitization, result transformations etc.

Template

<template name="booksearch">
  <form name="booksearch"><input type="search"/></form>
  <ul>
    {{#each hits}}
      <li>{{title}}</li>
    {{#each}}
  </ul>
</template>

Client: set up your helper

var options = {
  // cache the search results for 5 minutes
  keepHistory: 1000 * 60 * 5,
  // allow fast local searches on the cache
  localSearch: true
};
// feed the search to the title field only
var fields = ['title'];
// Set up your search
BookSearch = new SearchSource('books', fields, options);

/*
  get the search results reactively. mind you, this is not an invocation.
  you'll invoke the search within your event handler down below
*/
Template.booksearch.helpers({
  hits : function() {
    return BookSearch.getData();
  }
})

Template.booksearch.events({
  'submit form': function(e,t) {
    // listen for the submit event
    e.preventDefault();
    var options = {
      // this is your lang query param from the url
      lang: FlowRouter.getQueryParam('lang')
    };
    // value of the search input from your template
    var searchText = t.$('input').val();
    // invoke the search using the input and the language
    BookSearch.search(searchText,options);
  }
})

Server: set up your search

SearchSource.defineSource('books', function(searchText, options) {
  // make sure you do have a lang option or use a default one
  var lang = options.lang || 'english'
  if(searchText) {
    var regExp = buildRegExp(searchText);
    // use the input and lang to build your mongodb selector
    var selector = {title: regExp, language: lang};
    return Books.find(selector).fetch();
  } else {
    // don't return anything if nothing is searched for
    return [];
  }
});

function buildRegExp(searchText) {
  // copied over from the naive github example
  var parts = searchText.trim().split(/[ \-\:]+/);
  return new RegExp("(" + parts.join('|') + ")", "ig");
}

Upvotes: 1

Related Questions