I have a scenario where when I click on a link i need to change the route and also add send some params to the other state.
The issue here is the params are empty when I console it in other state
<div ng-repeat="items in vm.Items">
<a ng-click="vm.goToDetails(items.id)">{{items.title}}</a>
</div>
Controller:
vm.goToDetails = function(Id) {
$state.go('Details', {
'fid': Id
});
}
route:
$stateProvider.state('Details', {
url: '/details/:fid',
resolve: {
selectedProduct: ['$state', '$stateParams',
function($state, $stateParams) {
console.log($stateParams.fid) //getting empty string here
console.log($state.params.fid)//getting undefined here
}
]
}
});
Any help would be appreciated.
You need to specify the parameters name in the route url:
/some-route/:fid
I didn't find any issue with the code, may be the issue is with the injection of resolved parameter.
I created a DEMO with your code. This may be helpful to you.
Here is config,
app.config(function($stateProvider,$urlRouterProvider){
$stateProvider.state('Details', {
url: '/details/:fid',
templateUrl: 'detail.html',
controller: 'DetailController',
resolve: {
selectedProduct: ['$state', '$stateParams',
function($state, $stateParams) {
console.log($stateParams.fid) //getting empty string here
alert($stateParams.fid) //getting empty string here
return $stateParams.fid
}
]
}
});
$stateProvider.state('login',{
url: '/login',
templateUrl: 'login.html',
controller: 'LoginController'
});
$urlRouterProvider.otherwise('/login');
});
Controller that contains repeated object,
app.controller('LoginController',function($scope,$state){
$scope.Items = [{id: 1,title: "Title1"},{id: 2,title: "Title2"},{id: 3,title: "Title3"}]
$scope.goToDetails = function(Id) {
console.log(Id)
$state.go('Details', {
'fid': Id
});
}
})
This is the controller where you can inject selectedProduct
app.controller('DetailController',function($scope,$state,selectedProduct){
$scope.selectedProduct = selectedProduct;
})
PLEASE CHECK THIS DEMO
Related
Codes setting up the router (the two states have a parent-child relation):
.state("tab.my-profile", {
url: "/my/profile",
views: {
"tab-my": {
templateUrl: "templates/tab-my-profile.html",
controller: "MyProfileCtrl"
}
}
})
.state("tab.my-profile-mobileinput", {
url: "/my/profile/mobileinput",
views: {
"tab-my": {
params: {"mobile": null}
templateUrl: "templates/util-mobile-input.html",
controller: "MobileInputCtrl",
}
}
})
Codes in the controller of the parent state:
.controller("MyProfileCtrl", function ($scope, $state) {
$scope.goToMobileInput = function () {
$state.go("tab.my-profile-mobileinput", {"mobile": "123456"})
};
})
Codes in the controller of the child state:
.controller("MobileInputCtrl", function ($scope, $stateParams) {
alert($stateParams.mobile); // undefined
})
I can jump to the child state. But in the child state’s controller, I can’t receive the parameter (got an “undefined”). I’ve been stuck in this problem for hours. Could anyone help me find a way out? Thanks a lot in advance.
In my apps, I set parameters on url.
.state("tab.my-profile-mobileinput", {
url: "/my/profile/mobileinput/:mobile",
views: {
"tab-my": {
templateUrl: "templates/util-mobile-input.html",
controller: "MobileInputCtrl",
}
}
})
When a user attempts to visit my home page, I want to be able to redirect them to a different state based on query params.
For example, if URL is: http://example.com, then load the home page.
If URL is: http://example.com?channel=1, then don't load the home page and go to some other state right away.
Here's what I have (doesn't work):
$stateProvider
...
.state('default-template.home', {
url: '/?channel&campaign',
views: {
'': {
templateUrl: 'app/pages/home/home.html',
controller: 'HomeCtrl as vm'
}
},
resolve: {
data: ['$rootScope', '$stateParams', '$state', function($rootScope, $stateParams, $state) {
var channel = $stateParams.channel;
// If channel is 1, redirect
if (channel === 1) {
$state.go('default-template.other-state', {channel: channel});
}
}]
}
})
The problem seems to be that while both states get kicked off ($stateChangeStart event gets kicked off), the end result is the user always ends up on the home page.
Any thoughts on how to make this work?
You can use the $location built-in service to achieve this.
Your code must have an additional state for the fake path as below
$stateProvider
...
.state('default-template.fake.home', {
url: '/?channel',
views: {
'': {
templateUrl: 'app/pages/home/home.html',
controller: 'HomeCtrl as vm'
}
},
})
.state('default-template.home', {
url: '/?channel&campaign',
views: {
'': {
templateUrl: 'app/pages/home/home.html',
controller: 'HomeCtrl as vm'
}
},
resolve: {
data: ['$rootScope', '$stateParams', '$state', function($rootScope, $stateParams, $state) {
var channel = $stateParams.channel;
// If channel is 1, redirect
if (channel === 1) {
$state.go('default-template.other-state', {channel: channel});
}
}]
}
})
Your HomeCtrl should use the $location service to access the url as below
angular.controller('HomeCtrl',function($location,$state){
if($location.$$url= '') //check if it is empty
$state.go('default-template.home');
....................................
})
LIVE DEMO
I have a state as such:
.state('home.deletemsg', {
views: {
"contentworker#": {
url: '/delete/:entityname/:id/:redirectstate',
templateUrl: "Scripts/proteanapp/templates/delete.html",
controller: 'deletectrl',
controllerAs: 'del',
authenticate: true
}
}
Then in the controller I have:
return app.controller('deletectrl', ['$scope', '$rootScope', '$stateParams', function ($scope, $rootScope, $stateParams) {
debugger;
// check for ui router error
var del = this;
del.entityname = $stateParams.entityname;
del.entityid = $stateParams.id;
}]);
Calling $state.go from a controller like :
$state.go('home.deletemsg', { 'entityname': cd.Customer.Name, 'id': cd.Customer.CustomerID }, { 'location': false, 'notify': true });
But the $stateParams is empty, I don't understand why it is empty. I have tried putting an params object into the state and also resolve.
$stateParams.entityname //undefined
$stateParams.id //undefined
url option should be present there on state definition directly, not inside views object of state. But even your controller should not have been called the way you have configured your state.
Code
.state('home.deletemsg', {
//url should present here, rather than putting it inside `views`
url: '/delete/:entityname/:id/:redirectstate',
views: {
"contentworker#": {
templateUrl: "Scripts/proteanapp/templates/delete.html",
controller: 'deletectrl',
controllerAs: 'del',
authenticate: true
}
}
I want to be able to reload just the nested view of my application and attached a route parameter on so that I can have URL routing in my application. I cannot figure out how to do this, I initially had it working with a query like this:
$location.search('userId', user._id);
//http://localhost:9000/#/user/?userId=123456789
My desired URL is below, with the userId = 123456789
http://localhost:9000/#/user/123456789
My app.js file
$stateProvider
.state('index', {
url: '/',
views: {
'#' : {
templateUrl: 'views/layout.html'
},
'top#index' : {
templateUrl: 'views/top.html',
controller: function($scope, $state) {
$scope.userLogOut = function() {
$state.go('login');
};
}
},
'left#index' : { templateUrl: 'views/left.html' },
'main#index' : { templateUrl: 'views/main.html' }
}
})
.state('index.user', {
url: 'user:userId',
templateUrl: 'views/user/user.html',
controller: 'UserCtrl'
})
.state('index.user.detail', {
url: '/',
views: {
'detail#index' : {
templateUrl: 'views/user/details.html',
controller: 'DetailCtrl'
}
}
})
In my controller:
$state.reload('index.user.detail', {userId: $scope.user._id});
As you are using ui-router you can use $state.go('index.user', { userId: {{yourid}} });
To allow the query string parameter to work using ui-router write your state like this,
.state('index.user', {
url: 'user/?userId=:param',
templateUrl: 'views/user/user.html',
controller: 'UserCtrl'
})
That would allow this to work,
//http://localhost:9000/#/user/?userId=123456789
Without the query string parameter (your desired URL) would be this,
.state('index.user', {
url: 'user/:userId',
templateUrl: 'views/user/user.html',
controller: 'UserCtrl'
})
http://localhost:9000/#/user/123456789
I am having weird issue probably caching issue while navigating from grand-child(/dashboard/1/production) to parent(/dashboard).
Following are few screenshots:
The selections i.e Delphi-UI and production shouldn't persists.
Following is my snippet of application config:
$stateProvider
.state('root', {
url: '/',
views: {
'header': {
templateUrl: 'ngapp/templates/header.html'
}
}
})
// dashboard routes
.state('root.dashboard', {
url: 'dashboard',
views: {
'content#' : {
templateUrl: 'ngapp/home/templates/dashboard.html',
controller: 'DashboardCtrl',
controllerAs: 'vm'
}
}
})
.state('root.dashboard.app', {
url: '/{id:int}',
views: {
'body#root.dashboard' : {
templateUrl: 'ngapp/home/templates/dashboard-body.html',
controller: 'DashboardBodyCtrl'
}
}
})
.state('root.dashboard.app.env', {
url: '/:name',
views: {
'body#root.dashboard' : {
templateUrl: 'ngapp/home/templates/env-content.html',
controller: 'EnvContentCtrl'
}
}
});
And DashboardCtrl is:
controllers.controller('DashboardCtrl', ['$scope', '$http', '$state', '$timeout', 'appsFactory', function($scope, $http, $state, $timeout, appsFactory) {
$scope.envs = [];
$scope.deps = [];
$scope.envBtnText = $scope.appBtnText = "Choose here";
$scope.headerTitle = "Environment Configuration And Management";
$scope.appStatus = {
isopen: false
};
$scope.envStatus = {
isopen: false
};
appsFactory.list(function(data) {
$scope.apps = data;
});
}]);
Full controller code : http://goo.gl/BWtiU5
Project hosted here : https://github.com/budhrg/atlantis-dashboard
Also, navigating back to Atlantis UI(dashboard) doesn't reset data like
$scope.envs, $scope.deps, $scope.envBtnText and $scope.appBtnText.
What might be issue here? Am I missing anything?
Nested States & Views
When the application is in a particular state—when a state is "active"—all of its ancestor states are implicitly active as well. Below, when the "contacts.list" state is active, the "contacts" state is implicitly active as well, because it's the parent state to "contacts.list".
Your controller isn't getting re-instantiated (expected). There are a couple ways to handle this.
See:
How to make angular ui-router's parent state always execute controller code when state changes?