Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ember route with dynamic filter / search criterias

Tags:

ember.js

With the following problem I got stuck now for days. My use case is that I have a database with millions of addresses. From an web-application I would like to search them, display a list of resuls and later display information about a single address. One important goal is, to represent the search criteria as part of the URL. That way users can go back to previous searches or even construct the search by manipulating the URL. So I would like to have a URL like this:

http://localhost/#/searchresults?lastname=king&firstname=stephen&city=somecity

I don't manage to setup the router to process these kind of URLs. All a tried ended in a dead end. How to make ember go into the /searchresults route and how to have it forward those filter criterias using the RESTAdapter?

like image 290
Daniel Avatar asked Feb 17 '23 13:02

Daniel


1 Answers

Based on the answer from intuitivepixel I came up with the following solution.

I construct the following URL: http://somedomain.com/#/searchresults/?lastname=king&firstname=stephen&city=somecity

The way how this URL is contructed is not described here. In my case I use a my own view with a form and some event handlers.

The code that I got working looks like this:

App.Router.map(function() {
    this.resource("searchresults", { path: '/searchresults/:dynamic' });
});

App.SearchresultsRoute = Ember.Route.extend((function() {
    var deserializeQueryString = function (queryString) {
        if(queryString.charAt(0) === "?")
            queryString = queryString.substr(1);

        var vars = queryString.split('&'),
            i = 0, length = vars.length,
            outputObj = {};

        for (; i < length; i++) {
            var pair = vars[i].split('=');
            outputObj[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
        }
        return outputObj;
    };

    return {
          model: function(param) {
            var paramObj = deserializeQueryString(param.dynamic);
            return App.Searchresult.find(paramObj);
          }
        };
    })()
);

App.Store = DS.Store.extend({
    revision: 12,
    adapter: DS.RESTAdapter.create({
        namespace: 'api'
    })
});

App.Searchresult = DS.Model.extend({
    lastname: DS.attr('string'),
    firstname: DS.attr('string'),
    street: DS.attr('string'),
    hno: DS.attr('string'),
    zip: DS.attr('string'),
    city: DS.attr('string'),
    country: DS.attr('string'),
    birthdate: DS.attr('string')
});

This generates an HTTP GET request to my REST API:

http://somedomain.com/api/searchresults?lastname=king&firstname=stephen&city=somecity

My REST API responds with:

{"searchresults":
    [{"id":"2367507","lastname":"King","firstname":"Stephen","street":"Mainstreet.","hno":"21" ...},
     {"id":"3222409","lastname":"King","firstname":"Stephen","street":"Broadway","hno":"35" ...}
    ]}

And this then gets visualized with this template:

<h2>Searchresults</h2>
<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Street / Hno</th>
            <th>City</th>
            <th>Birthyear</th>
        </tr>
    </thead>
    <tbody>
    {{#each item in controller}}
        <tr>
            <td>{{item.firstname}} {{item.lastname}}</td>
            <td>{{item.street}} {{item.hno}}</td>
            <td>{{item.zip}} {{item.city}}</td>
            <td>{{item.birthdate}}</td>
        </tr>   
    {{/each}}
    </tbody>
</table>

If somebody finds a more elegant way, that does not require to use a custom deserializer, I will be glad to update the solution. The answer provided by (the other) Daniel that suggests http://somedomain.com/#/searchresults/king/stephen/somecity is not parctial for my case, since in the solution that I need, I have more than 10 different search criterias / filters. Users usually only choose to fill a few of them.

This examples base on ember-data revision: 12 and Ember 1.0.0-RC.3

like image 102
Daniel Avatar answered Mar 12 '23 19:03

Daniel