$stateParams empty ui router - javascript

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
}
}

Related

state params not getting in other state

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

AngularjS : Passing an object to controller using $state.go()

I am trying to pass an object to a controller via $state.go().
app.js :
.state('class', {
url: '/class/:programId',
views: {
'content#': {
templateUrl: 'class.html',
controller: 'ClassController'
},
data: {
requireLogin: true
}
}
}).state('classLevel', {
url: '/classLevel',
views: {
'content#': {
templateUrl: 'partials/classLevel.html',
controller: 'ClassLevelController',
params: { obj: null }
},
data: {
requireLogin: true
}
}
})
controller :
controllers.controller('ClassController', ['$scope', '$state', '$rootScope', '$stateParams', 'myService',
function($scope, $state, $rootScope, $stateParams) {
var myClass = myService.getList(url here);
myClass.then(function (data) {
// getting data here
});
$scope.loadClassLevel = function(summaryId, sessionId){
var CurrentDate = moment().unix();
var yourObj = {};
yourObj.currentTime = CurrentDate;
yourObj.summaryId = summaryId;
yourObj.sessionId = sessionId;
$state.go('patientFeelingLevel',{obj:yourObj});
}
});
controllers.controller('ClassLevelController', ['$scope', '$state', '$rootScope', '$stateParams',
function($scope, $state, $rootScope, $stateParams) {
console.log("$state :",$state);
});
I am trying to pass object from ClassController to ClassLevelController. But in console.log I am getting
params: Object
obj: null
Help me how to pass that object to next controller (ClassLevelController here).
You should use not $state to access the parameters that you passed, but $stateParams service.
Try this one:
console.log("$stateParams :",$stateParams);
That's because your state object will be always the same as at the start of your app.
Here is some example which shows that $stateParams is changing, but $state isn't.

UI router change templateUrl on click

Im trying to create a dynamic UI router when everytime you click a button it needs to return the templateUrl with the $stateParams.currentFloor changes only so it can get updated in the view on the screen.
Currently I have:
My setup:
app.config(function ($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
views: {
"menu-view": {
templateUrl: 'partials/menu.html'
},
"map-view": {
controller: 'mapViewController',
templateUrl: function ($stateParams) {
return 'partials/floors/floor-' + $stateParams.currentFloor + '.html'
}
}
}
})
});
My controller what needs to hold the data and pass it in the templateUrl function
app.controller('mapViewController', function ($scope, $stateParams) {
$scope.currentFloor = $stateParams.currentFloor;
$scope.currentFloor = 1;
$scope.addOne = function () {
$scope.currentFloor = $scope.currentFloor + 1;
return $stateParams.currentFloor = $scope.currentFloor;
};
});
And just simple a function what adds +1 to the scope everytime on a click
<button ng-click="addOne()"></button>
I think I'm pretty close but I have a hard time passing the data from my controller to the function what needs to change the templateUrl
Check the updated plunker here
One possible solution :
var app = angular.module('testTool', ['ui.router'])
.config(function($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/1');
$stateProvider
.state('home', {
url: '/:currentFloor',
views: {
"menu-view": {
templateUrl: 'menu.html'
},
"map-view": {
templateUrl: function ($stateParams) {
return 'floor-' + $stateParams.currentFloor + '.html'
},
controller: 'mapViewController'
},
}
})
})
.controller('mapViewController', function($scope, $stateParams, $state) {
$scope.addOne = function() {
$state.go('home', {currentFloor : parseInt($stateParams.currentFloor) + 1}, {reload: true})
};
});
Add param 'currentFloor in url params (url:'/:currentFloor'). Then reload state with this params : $state.go('home', {currentFloor : 2}, {reload: true})
Option reload:true is important for ui router reload the state when your are on the same state.
I suggest you to use resolve function if you need to do some work between $stateParams and object in your scope.
Try to add $state.go($state.current, {}, {reload: true}) after changing $stateParams.

AngularJS UI Router data persists when navigating from grand-child to parent

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?

How can you manually inject route resolve data inside a controller?

I have 2 routes that share a controller, one needs data resolved prior to the view loading, and the other does not need the resolved data.
Routing segment example:
...
when('/users', {
controller: 'UsersCtrl',
templateUrl: '/partials/users/view.html',
resolve: {
resolvedData : ['Accounts', function(Accounts) {
return Accounts.get();
}]
}
}).
when('/users/add', {
controller: 'UsersCtrl',
templateUrl: '/partials/users/add.html'
})
...
Controller example:
app.controller('UsersCtrl', ['$scope', 'Helper', 'resolvedData',
function($scope, Helper, resolvedData) {
// this works for the first route, but fails for the second route with
// unknown "resolvedDataProvider"
console.log(resolvedData);
}]);
Is there any way I can get the resolvedData in the controller without explicitly using the resolve name as a dependency? So a check can be performed?
Using the $injector does not work. I would like to do something similar to:
if ($injector.has('resolveData')) {
var resolveData = $injector.get('resolveData');
}
However this does not work even for the route that has the resolveData set ('/users'):
app.controller('UsersCtrl', ['$scope', 'Helper', '$injector',
function($scope, Helper, $injector) {
// this does not work -> fails with the unknown "resolvedDataProvider" as well
$injector.get('resolvedData');
}]);
Can this be done in angularjs? Or should I just create a new controller?
Thank you.
Looks like I figured out another way to go. The resolved data is part of the $route. So you can access it using:
app.controller('UsersCtrl', ['$scope', '$route', 'Helper',
function($scope, $route, Helper) {
if ($route.current.locals.resolvedData) {
var resolvedData = $route.current.locals.resolvedData;
}
}]);
If the other route doesn't need it, just inject undefined on that route:
router:
when('/users', {
controller: 'UsersCtrl',
templateUrl: '/partials/users/view.html',
resolve: {
resolvedData : ['Accounts', function(Accounts) {
return Accounts.get();
}]
}
}).
when('/users/add', {
controller: 'UsersCtrl',
templateUrl: '/partials/users/add.html',
resolve: {
resolvedData: function() {
return undefined;
}
}
})
controller:
app.controller('UsersCtrl', ['$scope', 'Helper', 'resolvedData',
function($scope, Helper, resolvedData) {
if(resolvedData){
//set some scope stuff for it
} else {
//do what you do when there is no resolvedData
}
}]);

Categories