# Ember flexible, dynamic search - best practice?

**URL:** <https://discuss.emberjs.com/t/ember-flexible-dynamic-search-best-practice/1082>\
**Category:** Design\
**Created:** [April 24, 2013, 12:48pm UTC](https://discuss.emberjs.com/t/ember-flexible-dynamic-search-best-practice/1082 "2013-04-24T12:48:00Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![kmandrup](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/kmandrup/32/14584_2.png) [@kmandrup](https://discuss.emberjs.com/u/kmandrup)\
**Post date:** [April 24, 2013, 12:48pm UTC](https://discuss.emberjs.com/t/ember-flexible-dynamic-search-best-practice/1082/1 "2013-04-24T12:48:01Z")

</div>

I would like to add a dynamic search form functionality to my ember app. What is best practice? It seems to me that using request parameters is not a recommended approach, but then how?

I would imagine I could do something like the following in my routes?

```
posts/search/:search_term

```

But what if the search is made up of a collection of drop-down selections or similar input controls (like a form) or not just a text search? For such a search, one or more of these search filters may be active for a given search operation. LEt’s say I have 1-3 search filters. Would this be the way to go?

```
posts/search/:search1/:search2/:search3

```

Or if I have only 2 filters active?

```
posts/search/:search1/:search2

```

I assume that the first matching route is executed, so I could do:

```
posts/search/:search1/
posts/search/:search1/:search2
posts/search/:search1/:search2/:search3

```

But this still seems like repitition and anti-pattern.

Would I simply have a `posts/search` route and then manually extract the request params from the request in my router (handler)? Does this even work with the `/#/` hash routing?

Thanks.

---

<div class="post-metadata">

**Author:** ![stusalsbury](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/stusalsbury/32/14560_2.png) [@stusalsbury](https://discuss.emberjs.com/u/stusalsbury)\
**Post date:** [April 24, 2013, 5:01pm UTC](https://discuss.emberjs.com/t/ember-flexible-dynamic-search-best-practice/1082/2 "2013-04-24T17:01:42Z")

</div>

I’d say the restful norm would be [http://example.com/posts?term1=xyz&term2=pdq](http://example.com/posts?term1=xyz&term2=pdq). [http://example.com/posts/search/term1=xyz;term2=pdq](http://example.com/posts/search/term1=xyz;term2=pdq) should work according to HTTP spec.

Thank you for bringing this up – it only just dawned on me that I haven’t seen any mention of this in Ember docs (for the router) or the little I’ve seen of the extant data adapters (for the service calls). Hmm. Kind of a big gap in support for restful pages and services.

---

<div class="post-metadata">

**Author:** ![kmandrup](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/kmandrup/32/14584_2.png) [@kmandrup](https://discuss.emberjs.com/u/kmandrup)\
**Post date:** [April 24, 2013, 5:33pm UTC](https://discuss.emberjs.com/t/ember-flexible-dynamic-search-best-practice/1082/3 "2013-04-24T17:33:29Z")

</div>

Yeah, that is the “naïve” approach that we would use in a traditional Model2 MVC app, such as Rails or Spring, but… not sure how it would work with Ember, since it uses the “anchor” part of the url (after the `#` to resolve a path). I guess I can use `window.location.hash`, but I wonder if the Router simply discards whatever part of the URL remains after it has matched a route? I can find no mention of how to access the url params, only the “params” which as I understand it only refer to the dynamic part of a Route path.

```
/#/posts/search/:search

```

So a query of the form “Copenhagen 2 km radius” could be decoded to form a valid Ember route:

```
/#/posts/search/copenhagen%202%20km%20radius

```

Or using underscore as spaces

```
/#/posts/search/copenhagen_2_km_radius_with_3_rooms

```

Then I could use RegExp to extract the search terms from the `:search` param

```
var radius = params.search.match(/(\d+)\s*\km\s+radius/i)
var location = ??

```

I guess this approach could be made to work?

---

<div class="post-metadata">

**Author:** ![stusalsbury](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/stusalsbury/32/14560_2.png) [@stusalsbury](https://discuss.emberjs.com/u/stusalsbury)\
**Post date:** [April 24, 2013, 5:41pm UTC](https://discuss.emberjs.com/t/ember-flexible-dynamic-search-best-practice/1082/4 "2013-04-24T17:41:12Z")

</div>

I didn’t realize the question had anything to do with server technology. It it really related?

What I was noticing was that the router and the data adapters speak in hierarchies and not boolean parameters.

---

<div class="post-metadata">

**Author:** ![kmandrup](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/kmandrup/32/14584_2.png) [@kmandrup](https://discuss.emberjs.com/u/kmandrup)\
**Post date:** [April 24, 2013, 6:06pm UTC](https://discuss.emberjs.com/t/ember-flexible-dynamic-search-best-practice/1082/5 "2013-04-24T18:06:16Z")

</div>

This question has nothing to do with the server.

You can extract the URL options this way:

> <https://stackoverflow.com/questions/5448545/how-to-retrieve-get-parameters-from-javascript>

```
var options = decodeURIComponent(window.location.search.slice(1))
                      .split('&')
                      .reduce(function _reduce (/*Object*/ a, /*String*/ b) {
                        b = b.split('=');
                        a[b[0]] = b[1];
                        return a;
                      }, {});

```

> **[Array.prototype.reduce() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce)**
>
> The reduce() method executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element.
> The final result of running the reducer across all elements...

JS `reduce` can be used just fine with modernizer.js.

However, it looks like Ember normalizes the url into the form `/x/y/z` and discards anything after `?` Otherwise `#/posts/1?a=7` would result in a lookup posts: {post\_id: ‘1?a=7’}. It doesn’t look like the discarded options and made accessible from within the route or router. Not sure if this is intentional by design or if it’s a good or bad thing. It looks to me that going the URL options route is a “no go” at this point. Perhaps in the future, the `ApplicationRoute` could me made to extract the options before normalizing the URL path?

---

<div class="post-metadata">

**Author:** ![fanta](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/fanta/32/14645_2.png) [@fanta](https://discuss.emberjs.com/u/fanta)\
**Post date:** [May 20, 2013, 3:27pm UTC](https://discuss.emberjs.com/t/ember-flexible-dynamic-search-best-practice/1082/6 "2013-05-20T15:27:04Z")

</div>

Yeah, I remember I saw kind of the same question on stackoverflow. The solution that I read there, was to put the query string before the #, so you can access it later.

Take a look here [https://github.com/emberjs/ember.js/issues/1773](https://github.com/emberjs/ember.js/issues/1773)

---

<div class="post-metadata">

**Author:** ![gunziptarball](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/gunziptarball/32/4827_2.png) [@gunziptarball](https://discuss.emberjs.com/u/gunziptarball)\
**Post date:** [September 19, 2013, 7:21pm UTC](https://discuss.emberjs.com/t/ember-flexible-dynamic-search-best-practice/1082/7 "2013-09-19T19:21:38Z")

</div>

This is an incredibly helpful forum post, thank you all for bringing up the discussion!

I’m new to Ember, and am still struggling with routing…I’m trying to do something similar to this:

```auto
App.Router.map(function() {
  this.route('search', {path: '/search/*query'});
  this.route('incidents', {path: '/incidents/*query'});
});

App.SearchRoute = Ember.Route.extend({
  model: function(params) {
    // using jquery-bbq-deparam
    return $.deparam((params && params.query) || '');
  },
  setupController: function(controller, model) {
    controller.set('model', model);
  }
});

App.IncidentsRoute = Ember.Route.extend({
  model: function(params) {
    var filter = $.deparam(params.query);
    return Ember.RSVP.Promise(function(resolve, reject) {
      // use filter object to construct AJAX request...model comes from REST service
    });
  },
  setupController: function(controller, model) {
    controller.set('model', model);
  }
});

```

Here are my questions:

1. Is there some way I can update the url just before the transition from `#/search` to `#/incidents/fromDate=yyyy-mm-dd;toDate=yyyy-mm-dd` so when the user hits the back button, the search form can be restored to its last state?
2. Should I not be using a model in my search controller to store current form values? I know it’s “application state” and not “persisted state,” but I want the user to be able to modify their query without starting from scratch…so, doesn’t this have to be held in the URL?
3. Am I just completely missing the point here?! LOL 😛

Thanks!
