angularjs ui-router query string parameter support

angularjs ui-router is pretty cool, we use it in our app now but have not yet used query string parameters (e.g. ?p1=age&p2=height). But now we need to.
  • we're now adding a feature which is basically a report generator and its a good use case for query string parameters
  • once on the page then you're basically in that ui-router "state"
  • users can select filters etc. from dropdowns which will reload the data but should not destroy/recreate any controllers or ui widgets (we stay on the page and do not state transition)
  • yet we do want to update the url for deep links and back button support
  • we don't know the complete list of possible filter choices, but know it should be data driven and will change by report 
  • urls to support this report feature are will be something like thus
    • /reports 
    • /reports/sales 
    • /reports/sales?region=west&time=weeks
  • so we need to use query string parameters
Below are some of the things I discovered with ui-router query string support (we're using ui-router v0.2.0 so some of this may be changed in latest v0.2.10)

ui-router supports query string params in state urls like so:
url: "/contacts?myParam1&myParam2"
// will match to url of "/contacts?myParam1=value1&myParam2=wowcool"
I setup this state:
             .state('report.detail', {
                url: '/report/{name}?region&time',
                templateUrl: 'report.html',
                controller: 'ReportController'
            })

when I call it as follows it works and will create url: /report/sales?region=west
        <a ui-sref="report.detail({name: 'sales', region: 'west'})">West</a>

when I call it as follows it works and will create url: /report/sales?region=west&time=month

        <a ui-sref="report.detail({name: 'sales', region: 'west', time: 'month'})">West Q1</a>

not setting the query string param works ok too, will create url: /report/sales
        <a ui-sref="report.detail({name: 'sales'})">All</a>

You can also call in your js code using state.go() e.g.
        $state.go('report.detail', {name: 'sales', region: 'west', time: 'month'});


But we need something like a querystring wildcard, however the following will not work
   url: '/report/{name}?{path:.*}'
...thats because its for paths, not query string params

If you have a small known finite set you could go with listing all your possible params e.g.:
  url: '/report/{name}?region&time&other&more&denis&guess',


But we don't have a small known finite set of filters (its data driven) so I'm using this approach
             .state('report.detail', {
                url: '/report/{name}?options',
                templateUrl: 'report.html',
                controller: 'ReportController'
            })

<a ui-sref="report.detail({report: 'sales', options: 'west&time=week'})">West</a>

...where options is a placeholder for the whole querystring (set options to null if there are none)

This solution does mean I need to manage the query string param list more myself (build&parse it) but it also supports a wider list of possibilities and no need to change code when new filters are added.

Comments

  1. Hi, great post. I'm trying to solve the same problem. Have you come up with a better solution or is this the only possibility?

    ReplyDelete
    Replies
    1. Hi, thanks!
      No, I have not come up with another solution. I expect there are other possibilities but this is what we've gone with.

      Delete
  2. how to pass variable to match field in query eg.
    {"match":{
    "fileldname":"filedvalue"//-->replace with variable
    }

    ReplyDelete
  3. thanks for providing such blog

    ReplyDelete

Post a Comment

Popular posts from this blog

deep dive into Material UI TextField built by mui

angular js protractor e2e cheatsheet

react-router v6.4+ loaders, actions, forms and more