Question

I have an URL that will allow me to filter a list of courses. This is the format of the URL :

www.xxxxx/#/filter/All-Course/Languages-All-All/All-All/hour(s)/All/All/All/Anyone/1

By this url I want the list of courses that have Course as type , Languages as Category and their duration is in hour(s)

This is the URL of the client app (written with Angular.js). What I do is read the params in the url and make a call to a webservice that will get me the list of courses with the given critters.

This URL is ugly since it contains a lot of 'All' wildcards( the client did not like it ) .

I want to remove the 'All' keyword. The problem that I face is that I will no longer Know which keyword is relative to which type of filter. The second problem is that this url could be sent to another person ( another browser ) and I should get the same result as in the first browser.

The solution That I see(hope it's not the unique one) making the filter as key value the url will be like this :

/filter/Type:Course/Category:Language....

This is good in small number of filters but very long in case of big number of filters( I have 12). the ideal solution is having an URL like this :

/filter/Course/Language....

Any clue how I could achieve this ?

Was it helpful?

Solution 2

I have a feeling this should be handled in the backend part. The type of filter can be figured out from its name unless some filter names occurs in several types, and in that case, the only solution is to change their name to make them unique. If you have no overlap between your tags, the problem becomes trivial.

I would separate mandatory filters with '/' and optional ones with '-' and let the backend do the dirty sorting.

To simplify things, I'd add a 'seo_tag' field (or a new table called seo_filters or so) in the tables where you apply your filters and have a uniqueness validation across those tables.

OTHER TIPS

You can achieve something like http://www.springest.co.uk/agriculture-horticulture/animal-care using filtering by matching url segments to unique regexp patterns. For example they use daytime for Daytime filter because it doesn't match any other filter, and for Vocational Level filter they use vocational-level-[2-4] ...

So the idea is to determine patterns that only match a unique filter then do the matching and activate each filter. In your case, if we make the following assumptions:

  • Hours is the only filter with a numeric value
  • Type is either course or other and are reserved values no filter can match them.
  • Language starts with language-

We know that filters match a single pattern, if a segment is numeric it's hours, if starts with language it's language and if course or other it's type. Then your logic can look like this:

var App = angular.module('App', ['ngRoute']);

var patterns = {
    type: /(course|other)/,
    hours: /([0-9]+)/,
    language: /language-(.*)/,
};

App.config(function ($routeProvider) {
    $routeProvider
        .when('/filter/:filter*',  {templateUrl: 'aa.html', controller: 'FilterCtrl'})
        .otherwise({redirectTo: '/'});
});

App.controller('FilterCtrl', function ($routeParams, $location) {
    var segments = $routeParams.filter.split('/');
    segments.forEach(function (el) {
        for (var filter in patterns) {
            var res = el.match(patterns[filter]);
            if (res !== null) {
                console.log("Activate filter ", filter, " with params", res[1]);
            }
        }
    });
});

This approach makes filtering very flexible so you can change filters order, also you can remove or add new filters easily like the case of the website.

You should pay attention to changes that may occur in future, if a modification in business logic or naming convention will break the filter, so choose patterns wisely, hope I helped.

As you are in control of the url, you really should use the goold old query parameters for this. It makes the Url looks even better.

www.xxxxx/#/filter?language=all&course=type&duration=12

Queryparameter that are not set, can have a default.

With the $location.search() method, you have access to these queryparams.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top