AngularJS 1.5, using ui-router and components.
How do I pass a parameter inside a component using the ui-sref directive?
header.html:
<a ui-sref="dashboard({contentType: 'company'})">Company</a>
app.js:
.state('dashboard', {
url: "/dashboard",
component: "dashboard",
resolve: {
}
})
dashboard-component.js:
angular.module('myModule').component('dashboard', {
templateUrl: '/views/admin/dashboard.html',
controller: DashboardController,
binding: {
contentType: '<' // This is not working...
}
});
dashboard.html: (Expects to see contentType in here - but No...)
contentType: {{$ctrl.contentType}}
You need to tell your state that it could be called with some params. There are two ways you can have params. Here's a simple explanation:
Params that are part of URL
.state('dashboard', {
url: "/dashboard/:contentType",
component: "dashboard",
resolve: {
...
}
})
Params that are not part of URL
.state('dashboard', {
url: "/dashboard",
params: {contentType: null},
component: "dashboard",
resolve: {
...
}
})
EDIT: If you see, In the plunker I provided in comments, they are not directly trying to use the param value in controller, but they are using it to get something resolved.
Now, coming to your problem's solution,
One way is, you can inject $stateParams in controller and use $stateParams.tester.
Or, if you want, you can also use resolve to directly get the passed value, like:
$stateProvider.state('userlist', {
url: '/users',
params: {
tester: null
},
component: 'users',
resolve: {
tester: function($stateParams) {
return $stateParams.tester;
}
}
});
second example plunker
Add url param contentType in the state
.state('dashboard', {
url: "/dashboard/:contentType",
component: "dashboard",
resolve: {
}
})
Related
I am trying to pass data from one controller to another using $stateParams but getting null instead of valid data:
Please find my route code below:
.state("root.home", {
url: "/home",
abstract: true,
template: homeHtml,
controller: "HomeCtrl as ctrl",
})
.state("root.home.content", {
url: "",
params: {
userId: null,
},
views: homeView,
})
Controller A code:
$state.go("root.home.content", {userId}); // getting correct UserId
HomeCtrl code:
// In its constructure I injected the $stateParams
init() {
console.log($stateParams); // getting undefined here
if ($stateParams && $stateParams.userId) {
this.loadUser($stateParams.userId);
}
}
Pass your parameter as below
$state.go("root.home.content", {'userId': userId});
//This userId should be a valid variable inside your Controller A
And also you should edit your router as below,
.state("root.home.content", {
url: "/:userId",
params: {
userId: null,
},
views: homeView,
})
Otherwise it will not show in the url & cannot access from $stateParams
I fixed this by adding params to parent root instead of child. The correct code is:
.state("root.home", {
url: "/home",
params: {
userId: null,
},
abstract: true,
template: homeHtml,
controller: "HomeCtrl as ctrl",
})
.state("root.home.content", {
url: "",
views: homeView,
})
controllerA from state A
$state.go('account.accountRegister', {accountType: $stateParams.accountType, acName: acName})
State defined in app.js
.state('account.accountRegister', {
url: '/:accountType/register',
params: {accountType, acName},
views: {
'mainView#':{
templateUrl: 'app/views/registration.html',
controller: 'registrationController'
}
}
})
controllerB from state B
console.log($stateParams.acName); // is getting undefined
How to use acName in the controller without showing in the url part of the state?
I came up with a solution
.state('account.accountRegister', {
url: '/:accountType/register',
params: {
acName: {
value: 'defaultValue',
squash: false
}
},
views: {
'mainView#':{
templateUrl: 'app/views/registration.html',
controller: 'registrationController'
}
}
})
For more info on squash property of the params object:
https://ui-router.github.io/docs/0.3.1/#/api/ui.router.state.$stateProvider
I have states that look like this:
$stateProvider.state('base', {
url: '/base',
redirectTo: 'base.all',
template: '<div ui-view></div>'
})
.state('base.all', {
parent: 'base',
url: '?someQuery&another',
params: {
someQuery: null,
another: null
},
views: {
'': {
template: '<div>base.all</div>',
controller: function($stateParams){
console.log($stateParams.someQuery);//undefined
console.log($stateParams.another);//undefined
}
}
//some views
}
})
.state('base.all2', {
parent: 'base',
url: '/subPath?someQuery&another',
params: {
someQuery: null,
another: null
},
views: {
'': {
template: '<div>base.all2</div>',
controller: function($stateParams){
console.log($stateParams.someQuery);//foo
console.log($stateParams.another);//bar
}
}
//some views
}
});
I listen to the event $stateChangeStart and do $state.go when redirectTo is present.
My problem now is if I go to the url /base?someQuery=foo&another=bar
It will correctly go to the base.all-state but the $stateParams of the base.all-state will be empty. I don't want this state to have a subPath. The child state will only get the urlParameters set to $stateParams if it has its own subPath like /base/subPath?someQuery=foo&another=bar then it works fine and everything is set to $stateParams.
Is my attempt to have a subState with no subUrl, but only the queryParameters, possible? If so how?
It was as simple to not use the redirectTo and set parent state to abstract.
I think I was too blinded with the use of redirectTo.
And I'm not getting any warnings when routing /base, it seems it will automatically find the state base.all and everything works as expected.
I want to be able to pass some state params that will show up in the route, and some that won't.
It would be nice to be able to do this:
.state('widgetadmin.widgets.widget', {
url: '/widget/{widgetId}/{friendlyName}',
views: {
"sub#widgetadmin": {
controller: 'WidgetAdminController as vm',
templateUrl: 'widgetadmin/widgets/widget.tpl.html',
params: { widgetHref: null }
}
},
data:{ pageTitle: 'Edit Widget' }
}
Then pass it like this:
$state.go('widgetadmin.widgets.widget',
{widgetId: widget.id, friendlyName: slug, widgetHref: widget._links.self.href},
{reload: true});
But when I try to access it, it's undefined:
var something = $stateParams.widgetHref;
How can I pass some state params in route, and some not?
Needed to put the params in a different place:
.state('widgetadmin.widgets.widget', {
url: '/widget/{widgetId}/{friendlyName}',
views: {
"sub#widgetadmin": {
controller: 'WidgetAdminController as vm',
templateUrl: 'widgetadmin/widgets/widget.tpl.html'
}
},
data:{ pageTitle: 'Edit Widget' },
params: { widgetHref: null }
}
I have the following state defined in my app module.
$stateProvider
.state('app', {
abstract: true,
url: '/',
views: {
'header': {
templateUrl: 'header.tpl.html'
},
'content': {
template: 'Content goes here'
},
'footer': {
templateUrl: 'footer.tpl.html'
}
}
});
But, I want to put header and footer in separate angular modules and load them as module dependency. Like - app.header & app.footer
Since, I can not redeclare a state. And, two states with same url doesn't work. So, is there any way I can achieve this?
Probably this is a bit old, but I guess answering might be useful as a future ref.
Have a look at this issue on ui-router GitHub, it seems to me that it could help.
The gist of the thing is represented by the following 2 code blocks:
// File1.js
angular.module('myApp').config(function($stateProvider) {
$stateProvider
.state("toplevelfeature", {
url: '/topleavelFeature'...
})
.state("toplevelfeature2", {
url: '/topleavelFeature2'...
})
.state("toplevelfeature.midfeature", {
url: '/midFeature'...
})
.state("toplevelfeature.midfeature2", {
url: '/midFeature2...'
})
.state("toplevelfeature.midfeature.anothernestedfeature", {
url: '/anothernestedfeature...'
})
});
// File2.js
angular.module('myApp').config(function($stateProvider) {
$stateProvider
.state("toplevelfeature.midfeature.anothernestedfeature.home", {...
})
.state("toplevelfeature.midfeature.anothernestedfeature.detail", {...
})
.state("toplevelfeature.midfeature.anothernestedfeature.other", {...
})
});