I've tested this in chrome, and added a break in the $scope.init in Ctrl2
but then when I go to route2 from route1, the chrome debugger stays at $scope.init of Ctrl2, but I see that ctrl1.html is still there.
.state("main.route1", {
url: "/route1",
controller: 'Ctrl1',
templateUrl: 'views/ctrl1.html'
})
.state("main.route2", {
url: "/route2",
controller: 'Ctrl2',
templateUrl: 'views/ctrl2.html'
})
So, how does the ui-router work? Isn't it supposed to go to ctrl2.html, and then execute Ctrl2? Why did it enter Ctrl2 but the ctrl1.html is still displayed?
I'm not sure if it is the same in ng-view, I haven't tested that.
Check js console to make sure you don't have errors in your angular controller
Add following run block to your module to catch state change error
.run(function ($rootScope, $state) {
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams){
console.log(fromState.name + ' to ' + toState.name);
});
$rootScope.$on('$stateChangeError',
function (event, toState, toParams, fromState, fromParams, error) {
alert(error);
event.preventDefault();
});
});
Related
Here imgetting Error in $statechangStart Here im trying to checking my credentials in $statechageStart
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('Login',{
url:'/LoginService',
templateUrl: '/ApiClient/Home/LoginPage.html',
controller:'LoginController'
})
$urlRouterProvider.otherwise('/')
})
.run(function ($rootScope) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams, options, $scope, $state) {
debugger;
if (toState.module == "Private" && sessionStorage.getItem('employee')!=null) {}
else {
event.preventDefault();
$state.go('Login');
}
You need to inject $state to your .run , otherwise it is undefined
.run(function ($rootScope, $state)
EDIT
It's a bad practice to use $state.go in $stateChangeStart event. For your purposes, you'd better apply the state.go after setting a timeout
$timeout($state.go.bind(null, 'Login'), 3000);
This question already has answers here:
Cannot get to $rootScope
(3 answers)
Closed 5 years ago.
I am using angular 1.5.x
Below is my routing logic but I am not able to get a handle of the rootScope.
Please can you advise what could be wrong?
UPDATE: I have updated the routing logic as per the answer post below.
I am still not able to hit the controller.
(function() {
'use strict';
angular
.module('icebergApp')
.config(setupRouting);
setupRouting.$inject = ['$stateProvider', '$urlRouterProvider', '$rootScope'];
function setupRouting($stateProvider, $urlRouterProvider, $rootScope) {
$urlRouterProvider.otherwise("/iceberg-ui");
$stateProvider
.state('iceberg.reconlist', {
url: "/iceberg-ui",
templateUrl: "app/iceberg/reconlist/reconlist.view.html",
controller: 'ReconListController as vm'
})
$rootScope.$on('$stateChangeStart',function(event, toState, toParams, fromState, fromParams){
console.log('$stateChangeStart to '+toState.name+'- fired when the transition begins. toState,toParams : \n',toState, toParams);
});
$rootScope.$on('$stateChangeError',function(event, toState, toParams, fromState, fromParams, error){
console.log('$stateChangeError - fired when an error occurs during transition.');
console.log(arguments);
});
$rootScope.$on('$stateChangeSuccess',function(event, toState, toParams, fromState, fromParams){
console.log('$stateChangeSuccess to '+toState.name+'- fired once the state transition is complete.');
});
$rootScope.$on('$viewContentLoading',function(event, viewConfig){
console.log('$viewContentLoading - view begins loading - dom not rendered',viewConfig);
});
$rootScope.$on('$stateNotFound',function(event, unfoundState, fromState, fromParams){
console.log('$stateNotFound '+unfoundState.to+' - fired when a state cannot be found by its name.');
console.log(unfoundState, fromState, fromParams);
});
}
}());
CONTROLLER
(function() {
'use strict';
var myApp = angular.module('iceberg.reconlist', ['ui.router']);
myApp.controller('ReconListController', ReconListController);
ReconListController.$inject = ['ReconListService'];
function ReconListController(ReconListService) {
var vm = this;
}
}());
MODULE
(function() {
'use strict';
angular.module('icebergApp', [
'ui.router',
'iceberg.reconlist'
]);
angular.module('iceberg.reconlist', [
]);
}());
$rootScope is not available in .config(). Only providers are available there. The thing you must do is splitting your code to put the $rootScope part into a .run method.
angular
.module('app')
.config(setupRouting);
setupRouting.$inject = ['$stateProvider', '$urlRouterProvider'];
function setupRouting($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/iceberg-ui");
$stateProvider
.state('iceberg.reconlist', {
url: "/iceberg-ui",
templateUrl: "app/iceberg/reconlist/reconlist.view.html",
controller: 'ReconListController as vm'
})
}
}());
angular.module('app').run(setupRoutingEventListeners);
setupRouting.$inject = ['$rootScope'];
function setupRoutingEventListeners($rootScope) {
$rootScope.$on('$stateChangeStart',function(event, toState, toParams, fromState, fromParams){
console.log('$stateChangeStart to '+toState.name+'- fired when the transition begins. toState,toParams : \n',toState, toParams);
});
$rootScope.$on('$stateChangeError',function(event, toState, toParams, fromState, fromParams, error){
console.log('$stateChangeError - fired when an error occurs during transition.');
console.log(arguments);
});
$rootScope.$on('$stateChangeSuccess',function(event, toState, toParams, fromState, fromParams){
console.log('$stateChangeSuccess to '+toState.name+'- fired once the state transition is complete.');
});
$rootScope.$on('$viewContentLoading',function(event, viewConfig){
console.log('$viewContentLoading - view begins loading - dom not rendered',viewConfig);
});
$rootScope.$on('$stateNotFound',function(event, unfoundState, fromState, fromParams){
console.log('$stateNotFound '+unfoundState.to+' - fired when a state cannot be found by its name.');
console.log(unfoundState, fromState, fromParams);
});
}
I am using UI Router in my angular app. I am trying to integrate state change events, but they are not firing on state change. Everything else is working fine and there is no error in console. I came across following similar questions, but none of the solution worked for me:
$rootScope.$on("$routeChangeSuccess) or $rootScope.$on("$stateChangeSuccess) does not work when using ui-router(AngularJS)
angular + ui-router: $stateChangeSuccess triggered on state b but not on a.b
Following is my Angular code:
(function() {
angular.module("bootdemo", [
"ngResource",
"ui.router",
"bootdemo.core",
"bootdemo.index"
])
.run(function ($rootScope, $location, $state, $stateParams) {
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){
alert("root change success");
})
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams, options){
alert("root change start");
})
$rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error){
alert("root change error");
})
})
.config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise('/');
$stateProvider
.state('index', {
url: "/",
templateUrl: '/index/templates/welcome.html',
controller: 'IndexController as vm'
})
.state('login', {
url: "/login",
templateUrl: '/index/templates/login.html',
controller: 'LoginController as ctrl'
})
.state('home', {
url: "/home",
templateUrl: '/index/templates/home.html',
controller: 'HomeController as ctrl'
})
});
}());
Left with no clue. I am not sure what I am missing.
StateChange events has been deprecated for ui.router >= 1.0
for the new ui.router use the following
StateChangeSuccess
$transitions.onSuccess({}, function() {
console.log("statechange success");
});
StateChangeStart
$transitions.onStart({}, function(trans) {
console.log("statechange start");
});
Check this migration guide for more information
If you are using the new ui-router (v1.0.0), the $stateChange* events will not work. You must use $transitions.on* hooks from now on.
You can read here.
https://ui-router.github.io/docs/latest/modules/ng1_state_events.html
https://github.com/angular-ui/ui-router/issues/2720
$state events are deprecated for angular version > 1.0.0.
now onward for change event we have to use $transitions
refer $transitions from here
Using ui-router how can I accomplish the following URL change? For example, when a user goes to "/page?hello=True" I want the url to change to "/page?status=hello".
$stateProvider.state('page', {
url: '/page/:id?status',
controller: 'MyCtrl as myCtrl',
templateProvider: function($templateCache) {
return $templateCache.get('templates/route.html');
}
});
You can use the stateChangeStart event in the app.run method to listen for state changes into that route, and change anything you want on the params. Something like this, might need to play with toState and toParams to get it right for you...
.run(['$state', '$rootScope', function($state, $rootScope) {
$rootScope.$on('$stateChangeStart', function(e, toState, toParams, fromState, fromParams) {
if (toState.name === 'invitation') {
//change toParams to whatever you want
}
});
});
I'm using this to catch errors and redirect to an error page
module.run(function ($state, $rootScope, translateService) {
$rootScope.$on("$stateChangeError", function (event, toState, toParams, fromState, fromParams, error) {
$state.go("app.error");
});
});
But this moves to the error state and changes the URL. I want to go to the error page and keep the URL to the page with the error.
I've tried using the location option,$state.go("app.error", null, { location: false }), but it keeps the URL of the state I'm coming from and not the one with the error.
Can I somehow go to the error state and keep the URL or go to the error state and then change the URL back to the URL of toState?
I solved it by sending the error information to the error state and then set the url with $location.path there.
module.run(function ($state, $rootScope) {
$rootScope.$on("$stateChangeError", function (event, toState, toParams, fromState, fromParams, error) {
$state.get("app.error").$error = {
toState: toState,
toParams: toParams,
fromState: fromState,
fromParams: fromParams,
message: error.message,
stack: error.stack
};
$state.go("app.error");
});
});
module.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider.state("app.error", {
url: "/error",
resolve: {
error: function () {
return this.self.$error;
}
},
templateUrl: "app/error.tpl.html",
controller: function ($state, $scope, $log, $location, error) {
if (error) {
$location.path($state.href(error.toState, error.toParams).replace(/^#/, ""));
$log.error(error.message, error.stack);
}
$scope.error = error;
}
});
});
I think this does the trick (I found this trick some time ago, it wasn't documented):
$rootScope.$on("$stateChangeError", function (event, toState, toParams, fromState, fromParams, error) {
event.preventDefault();
$state.go("app.error", {}, { location: false });
});
https://github.com/angular-ui/ui-router/wiki
look at the part about $stateChangeError
To add to the accepted answer, I did a small change that allowed me to retain the error url but attempt to go to the homepage (or whatever state you want) when the user tries to refresh:
controller: function ($state, $scope, $log, $location, error) {
if (error) {
$log.error(error.message, error.stack);
}else{
$state.go('app'); // or app.home or whatever
}
$scope.error = error;
}