ui-router default stateParam - angularjs

I have a state defined as such:
.state('dashboard.poor-calls', {
url: '/voice-quality/{callType}/{categoryTypeId}/{:categoryEntityId}/?{:tableView}',
template: '<poor-calls></poor-calls>',
reloadOnSearch: false
})
Notice that categoryEntityId is optional.
Is there a way to specify a default value for categoryEntityId if it's not provided in the state() definition, or does the controller of my <poor-calls> directive have to check for a missing categoryEntityId and assume the default value?

Yes, we can use params : {} configuration property:
.state('dashboard.poor-calls', {
url: '/voice-quality/{callType}/{categoryTypeId}/{:categoryEntityId}/?{:tableView}',
params: {categoryEntityId: 1}
template: '<poor-calls></poor-calls>',
reloadOnSearch: false
})
and we can even set what to do if that default value is provided, for example skip it from url (the squash setting):
params: {
categoryEntityId: {
value: 1,
squash: false,
},
},
See all the details here:
Angular ui router passing data between states without URL
How to pass parameters using ui-sref in ui-router to controller

Related

$state.go to state with URL parameter

I have a state with url parameter.
Something like:
.state('MyState', {
url: '/contacts/{personName}',
templateUrl: '/app/templates/contacts.html',
controller: 'ContactsController',
params: {
personName: null
}
})
now, I want to use the $state.go syntax and to be able to pass the personName param to the url with the parameter.
So for example, if I call:
$state.go('MyState', {personName: 'john'});
The address bar will show: http://localhost:8080/#!/contacts/john
Right now the address bar is showing http://localhost:8080/#!/contacts/ and I don't know how to force the url to contain the personName. Other than that it works fine.
Just add your parameters with a default value on your state definition. Your state can still have an Url value.
$stateProvider.state('MyState', {
url : '/url',
templateUrl : "/app/templates/contacts.html",
controller : 'ContactsController',
params: {personName: 'defaultName'}
});
and add the param to $state.go() and navigate
$state.go('MyState',{personName: "MIT"});
Refer this:$state.go() with Parameter
Hope it helps..!
In your state definition, when you define "params" you don't have to add param in the url so replace :
url: '/contacts/{personName}',
with
url: '/contacts',
While defining state use the following syntax
.state('myState', {
url: '/contacts/:personName',
templateUrl: '/app/templates/contacts.html',
controller: 'ContactsController',
params: {
personName: {
array: false
}
}
})
Note: "Person Name be visible in url"
Ref: https://ui-router.github.io/ng1/tutorial/helloworld

How to use AngularJS UI-router capture this URL with an optional parameter?

I'm using AngularJD ui-router to capture my URL and send two parameters from that URL to my controller. Here are my requirements:
The first parameter is a mandatory integer (id)
The second parameter is an optional string (slug)
The two parameters are separated by a /
I want it to ignore any single trailing /
Currently, I'm doing this:
$stateProvider.state('mystate',
{
url: '/mystate/{id:int}{slug:(?:/[^/]+)?}',
params: {
slug: {value: null}
},
templateUrl: 'partials/mystate.html',
controller: function($stateParams) {
console.log('$stateParams.id=',$stateParams.id, ' $stateParams.slug=',$stateParams.slug);
}
}
For URL: mystate/1 This correctly captures:
$stateParams.id=1, $stateParams.slug=null
For URL: mystate/1/myslug This captures the wrong value for slug:
$stateParams.id=1, $stateParams.slug=/asdad
For URL: mystate/1/ This doesn't capture anything.
For URL: mystate/1/myslug/ This doesn't capture anything.
How can I write this so that it captures all four of the aforementioned URLs properly but doesn't pass any of the /s to the controller?
For optional trailing slash, you need to set strict mode to false in a config block:
angular.module('yourModule').config(['$urlMatcherFactoryProvider', function($urlMatcherFactoryProvider) {
$urlMatcherFactoryProvider.strictMode(false);
}]);
For having optional parameters, there's a long discussion here. At the end, they suggest using squash:
$stateProvider.state('mystate',
{
url: '/mystate/{id:int}/:slug',
params: {
slug: {value: null, squash: true}
},
templateUrl: 'partials/mystate.html',
controller: ['$stateParams', function($stateParams) {
console.log('$stateParams.id=',$stateParams.id, ' $stateParams.slug=',$stateParams.slug);
}]
}
squash has good documentation, if you set it to true, it omits the parameter from URL when it has the default value.

How can i update $stateParams without reloading the ui-view? angular ui router

Get the context, angular, ui-router, nothing special, a root view built with 3 named ui-views.
so in index.html we have
<body>
<div ui-view='left'>
<div ui-view='center'>
<div ui-view='right'>
</body>
my route looks like
$stateProvider
.state('main', {
url: '/',
views: {
'left': {templateUrl: 'foo.html'},
'center': {templateUrl: 'bar.html'},
'right': {templateUrl: 'xyz.html'}
}
})
.state('main.b', {
url: '/b',
params: { foo: {value: 'bar'} }
views: { 'right#': {templateUrl: '123.html'} } // I wish to update $stateParams in 'left#' view
})
.state('main.c', {
url: '/c',
params: ...
views: { 'left#': ..., 'center#': ..., 'right#': .. }
});
Is there a way in going to b state to update the $stateParams in the 'center' and 'left' view?? I can get it using a service but i need to add a $watch to the variable I need and it looks a little bit hacky to me.
Going into c state I can actually get what I want, but the view is reloaded, and i wish to avoid this behaviour cause i have a canvas in the 'left' view.
You could use the following to go to a specific route without reloading the views:
$state.go('.', {parm1: 1}, {notify: false});
The last object literal represents the options which you can pass along to go. If you set notify to false, this will actually prevent the controllers from being reinitialized. The . at the beginning is the absolute state name or relative state path you wanna go to.
The important thing is the notify though.
I think that using "Dynamic params" is now a better solution:
When dynamic is true, changes to the parameter value will not cause the state to be entered/exited. The resolves will not be re-fetched, nor will views be reloaded.
$stateProvider.state('search', {
url: '/search?city&startDate&endDate',
templateUrl: 'some/url/template.html',
params: {
city: {
value: 'Boston',
dynamic: true
}
}
}
and then:
$state.go('.', {city: 'London'});
https://ui-router.github.io/ng1/docs/latest/interfaces/params.paramdeclaration.html#dynamic
https://github.com/angular-ui/ui-router/issues/2709
Quoting #christopherthielen from https://github.com/angular-ui/ui-router/issues/1758#issuecomment-205060258:
using notify: false is almost never a good idea, and is now
deprecated. Use reloadOnSearch if you must.
You can also try dynamic parameters in the 1.0 version (currently
1.0.0-alpha.3). In your state, configure a parameter as dynamic and implement the uiOnParamsChanged callback :
.state('foo', {
url: '/:fooId',
params: { fooId: { dynamic: true } },
controller: function() {
this.uiOnParamsChanged = function(changedParams, $transition$) {
// do something with the changed params
// you can inspect $transition$ to see the what triggered the dynamic params change.
}
}
});
For a demo, have a look at this plunker: http://plnkr.co/edit/T2scUAq0ljnZhPqkIshB?p=preview

ui-router, using default parameter if nothing was passed in the url

Is there any way to handle both /silukin/:start and /silukin, with condition if :start param not passed, then use '1' by default?
.state('app.silukin', {
url: "/silukin/:id",
views: {
'menuContent1': {
templateUrl: "templates/silukin.html",
controller: 'SilukinCtrl',
}
}
})
Check this API Reference. (click the $state - Provider). With latest UI-Router we can use new attributes for state defintion:
.state('app.silukin', {
url: "/silukin/:id",
views: {
'menuContent1': {
templateUrl: "templates/silukin.html",
controller: 'SilukinCtrl',
}
},
// define a parameter's default value
params: {
id: { value: "defaultValue" }
}
Check the API reference for more details
params (optional) object
A map which optionally configures parameters declared in the url, or defines additional non-url parameters. For each parameter being configured, add a configuration object keyed to the name of the parameter.
Each parameter configuration object may contain the following properties:
value
array
squash
-- (see more in that resource)

UI-Router - Change $state without rerender/reload of the page

I've been looking at these pages (1, 2, 3). I basically want to change my $state, but I don't want the page to reload.
I am currently in the page /schedules/2/4/2014, and I want to go into edit mode when I click a button and have the URL become /schedules/2/4/2014/edit.
My edit state is simply $scope.isEdit = true, so there is no point of reloading the whole page. However, I do want the $state and/or url to change so that if the user refreshses the page, it starts in the edit mode.
What can I do?
For this problem, you can just create a child state that has neither templateUrl nor controller, and advance between states normally:
// UPDATED
$stateProvider
.state('schedules', {
url: "/schedules/:day/:month/:year",
templateUrl: 'schedules.html',
abstract: true, // make this abstract
controller: function($scope, $state, $stateParams) {
$scope.schedDate = moment($stateParams.year + '-' +
$stateParams.month + '-' +
$stateParams.day);
$scope.isEdit = false;
$scope.gotoEdit = function() {
$scope.isEdit = true;
$state.go('schedules.edit');
};
$scope.gotoView = function() {
$scope.isEdit = false;
$state.go('schedules.view');
};
},
resolve: {...}
})
.state('schedules.view', { // added view mode
url: "/view"
})
.state('schedules.edit', { // both children share controller above
url: "/edit"
});
An important concept here is that, in ui-router, when the application is in a particular state—when a state is "active"—all of its ancestor states are implicitly active as well.
So, in this case,
when your application advances from view mode to edit mode, its parent state schedules (along with its templateUrl, controller and even resolve) will still be retained.
since ancestor states are implicitly activated, even if the child state is being refreshed (or loaded directly from a bookmark), the page will still render correctly.
REF: https://github.com/angular-ui/ui-router/wiki/Quick-Reference#statetransitiontoto-toparams--options
$state.transitionTo('yourState', params, {notify: false});
Adding my answer because I think it's different enough from the accepted answer and may be useful to others:
I had two states, begin and view, with a bunch of optional parameters being synced with the URL for view, like so:
$stateProvider
.state('begin',
{
url: '/',
template: '<app-element></app-element>'
})
.state('view',
{
url: '/View?param1&param2&...&paramN',
template: '<app-element></app-element>'
params: {
param1: {
value: null,
squash: true
},
...
}
});
The link function for <app-element> would run any time I tried to sync the parameters using $state.go. Using {notify: false, reload: false} did not work for me. The link function still ran each time. I'm on 0.2 so dynamic isn't an available param option, either. I followed #b0nyb0y's suggestion and turned it into a parent/child relationship, which worked:
$stateProvider
.state('app',
{
url: '/',
template: '<app-element></app-element>'
})
.state('app.view',
{
url: 'View?param1&param2&...&paramN',
params: {
param1: {
value: null,
squash: true
},
...
}
});

Resources