Denis Lins
Denis Lins

Reputation: 814

How can I force URL params to appear in URL in ui-router?

I have a simple users.list state, configured like this:

$stateProvider.state('users.list', {
  url: '/users/list?type',
  reloadOnSearch: false,
  templateUrl: 'templates/users/list.html',
  params: {
    type: { value: 'all' },
  },
});

I'm trying to force the type param to always appear in the URL. When I click on a link generated by the ui-sref directive, it works great. The problem happens when I access /users/list directly in the browser. Although the param is correctly configured into $state.params, it does not appear in the URL.

Usually that's not a big problem, but it becomes one when you need to use seasonal params. For instance, imagine that, by default, I want to only list new users, registered from the past week until now. I could do that setting a param from with the default value of today - 7 days, which would be different every day.

So, when the user shares the url without the param with someone, it can cause a lot of trouble, like: "Hey, delete the third one from the top for me, it's cheating.". If the person who receives the message decides to open the url in another day, the list will be different, and you can see what I'm worried about.

I couldn't find anything that could help me, so I'm asking here. Have anyone done that? Is it feasible?

Upvotes: 1

Views: 391

Answers (2)

Artur Kulig
Artur Kulig

Reputation: 551

I would suggest simply making another state without state parameter in URL, with onEnter function redirecting to state with required parameter filled.

Upvotes: 0

Radim Köhler
Radim Köhler

Reputation: 123861

There is a working plunker

We just have to use setting squash:

.state('users.list', {
  url: '/users/list?type',
  reloadOnSearch: false,
  templateUrl: 'templates/users/list.html',
  params: {
    type: {
      value: 'all',
      squash: false,
    },
  },
});

Check it here

For more details observe these:

EXTEND (updated working plunker)

In case, that we want the initial page to be also using the defaults, we can use this .otherwise() setting:

//$urlRouterProvider.otherwise('/users/list');
$urlRouterProvider.otherwise(function($injector, $location) {
    var state = $injector.get('$state');
    state.go('users.list');
    return $location.path();
});

Check that in action here and read more details here:

Upvotes: 1

Related Questions