I use angularjs(ui-route) in my project .
Before some states is loading I need to check the global variable in my project,
if global variable is null I need to redirect the user to specific state.
Any idea how can I implement it?
How do I check the global variable each time when state is changing?
UPDATE
My global variable is a field in service.
You need something like this:
angular.module('app')
.run(function(myService, $rootScope, $state) {
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {
if(myService.field) {
$state.go('ohMyGod');
}
});
});
Related
I have a function validateSesion that i need to call every time a controller is executed.
There is a way to trigger the function without putting the call to the function in all the controllers?
The way I would recommend accomplishing such a call would be to create event handlers for your route changes. This way every time you change your route or state (if you are using ui-router) you can run your code.
You would place this in your app's run function and attach the event handlers to the $rootScope as shown below:
angular.module('app', [
//Your Dependencies Here
]).run(init);
function init($rootScope, sessionService) {
//ngRoute
$rootScope.$on('$routeChangeStart', function (angularEvent, next, current) {
sessionService.validateSession();
});
//ui-router
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
sessionService.validateSession();
});
}
I want to run a function every time an Angular route is navigated to.
One option is I just add myFunction() to the top of every controller. Seems really repetitive. Is there a better way to run myFunction() every time $location changes?
If you are using ui-router, you can simply bind a function to the $rootscope.
See the stateChange section: https://github.com/angular-ui/ui-router/wiki#state-change-events
$rootScope.$on('$stateChangeSuccess',
function(event, toState, toParams, fromState, fromParams){ ... })
Using ngRoute once can hook up in event: $routeChangeStart and do different actions ...
app.run(function ($rootScope, $location) {
$rootScope.$on("$routeChangeStart", function (event, next, current) {
................
Is it possible to achieve the same using UI-Router?
Yes it's possible:
$rootScope.$on("$stateChangeStart",
function (event, toState, toParams, fromState, fromParams) {
Or just use
$scope.$on("$stateChangeStart",...);
If you want this to be triggered on a single page.
Check this answer here, that's the correct way to fix it. Removing all listeners could have unknown effects as there might be other places where listeners are added. You need to remove the one you added, not all of them.
Check this issue: Angular $rootScope $on listeners in 'destroyed' controller keep running
Copying code here for completeness too:
animateApp.controller('mainController', function($scope, $rootScope, service) {
$scope.pageClass = 'page-home';
var unregister = $rootScope.$on('service.abc', function (newval) {
console.log($scope.$id);
});
$scope.$on('$destroy', unregister);
});
Using Angularjs and UI-Router, trying to run a function every time state changes
$rootScope.$on('$stateChangeStart',
function(toState){
if(toState !== 'login')
UsersService.redirect();
})
I put this in .run() and i can successfully log out toState every time route changes. However, i can't seem to find the property which has the name of the state that we are going to. If someone can tell me where to find that, i think i should be in good shape.
Ended up with this and it does what i want.
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams){
if(toState.name !== 'login' && !UsersService.getCurrentUser()) {
event.preventDefault();
$state.go('login');
}
});
I have found the resolve map incredibly useful. If I request a state change within a page, if any resolves fail the state will not conclude/succeed as expected.
I do not seem to be performing anything within my app that would affect this behaviour, but I noticed that if I attempt to load a state directly in my app (through URL, eg. app.com/my/state) and the resolves fail, there is no state to fallback to, seeings this is the first route requested.
I would have assumed it would fallback to my 'otherwise' location, which is defined as '/'. Is this expected functionality? If not, is there an efficient way to handle this?
My current solution involves catching state errors and setting the location if there isn't a fromState (meaning the error occurred on the first state)
EbApp.run([
'$rootScope', '$location', '$timeout',
function($rootScope, $location, $timeout)
{
var first_state_error = $rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState)
{
// Redirect to the app root on a state error during the first state request
if ( ! fromState.name) {
$timeout(function()
{
$rootScope.$apply(function()
{
$location.path('/').search({});
});
});
}
// Remove watching state change errors once there is a fromState available
else {
first_state_error();
}
});
}
]);
If your state resolve function fails you don't go to "otherwise" route because the stateManager has found the route to go.
What you have to test is the toState name (not fromState), if you want to have different routes for errors, something like this:
$rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
if (toState.name === 'yourRouteName') {
return $state.go('whereverRoute');
}
return error;
});
or simply
$rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
$location.path('/')
});
if you want always redirect to your root