Is there a way to have an optional attribute at the beginning of the url in ui-router? If so, how?
I want to achieve sth like this:
.state(\'events\'
I tried to answer the similar (if not same) here:
Angular js - route-ui add default parmeter
There is a working plunker, solving the issue for a language
instead of for a city
(but the concept is the same)
so, we would/should introduce some super state 'root'.
In our case, we can even use some regex to limit allowed values - because it would be hard to guess what is
city
and what isevents
.state('root', {
url: '/{city:(?:Prague|Bristol|Denver)}',
abstract: true,
template: '<div ui-view=""></div>',
params: {lang : { squash : true, value: 'Prague' }}
})
What is important here is the setting params : {}
. It says, that the default value is 'Prague' - so that would be the city if none is selected. What is also important - it should be squashed, skipped if there is a match with 'Prague' param value:
params: {lang : { squash : true, value: 'Prague' }}
Now, we can introduce some nested state(s) which would declare 'root' as their parent:
.state('events',{
parent: 'root',
url: '/events/:id'
...
})
Check the working example (with a language instead of city) here. For more details see the original Q & A
It's probably bad practice to have two separate routes point to the same state, but nothing is keeping you from creating two different states that use the same resolutions/controller/template.
$stateProvider
.state('state1', {
url: "/:city/events/:id",
templateUrl: "partials/events.html",
controller: eventsCtrl
})
.state('state2', {
url: "/events/:id",
templateUrl: "partials/events.html",
controller: eventsCtrl
});
function eventsCtrl($scope){
// shared controller
}
Again, this is probably bad practice but I can't think of a better solution
I see no reason why you wan't do it in a standard ui-router
state setup.
DEMO
JAVASCRIPT
angular.module('app', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('state1', {
url: ':city/events/:id',
templateUrl: 'partials/events.html',
controller: 'EventsController'
})
.state('state2', {
url: ':abc/cities/:x/:y',
templateUrl: 'partials/cities.html',
controller: 'CitiesController'
});
})
.controller('EventsController', function($scope, $stateParams) {
angular.extend($scope, $stateParams);
})
.controller('CitiesController', function($scope, $stateParams) {
angular.extend($scope, $stateParams);
});