Here is the app.js of my project:
(function () {
'use strict';
angular
.module('app', ['ui.router', 'ngCookies', 'angular-inview', 'ngMaterial'])
.config(config)
.run(run);
config.$inject = ['$stateProvider', '$urlRouterProvider', '$mdThemingProvider'];
function config($stateProvider, $urlRouterProvider, $mdThemingProvider) {
$mdThemingProvider.theme('default')
.primaryPalette('deep-orange')
.accentPalette('teal', {
'default': 'A400'
});
$urlRouterProvider.otherwise('/app');
$stateProvider
.state('app', {
url: '/app',
data: {
clearenceLevel: 1
},
views: {
'': {
templateUrl: 'app/views/navbar.html',
}
}
})
.state('home.works', {
url: '/works',
templateUrl: 'app/views/works.html',
controller: 'WorksController as vm'
})
.state('login', {
url: '/login',
templateUrl: 'app/views/login.html',
controller: 'LoginController as vm',
data: {
clearenceLevel: 0
}
})
.state('register', {
url: '/register',
templateUrl: 'app/views/register.html',
controller: 'RegisterController as vm',
data: {
clearenceLevel: 0
}
});
}
run.$inject = ['$rootScope', '$location', '$state', '$cookieStore', '$http', 'AuthenticationService'];
function run($rootScope, $location, $state, $cookieStore, $http, AuthenticationService) {
$rootScope.globals = $cookieStore.get('globals') || {};
if ($rootScope.globals.currentUser) {
$http.defaults.headers.common['aimm-token'] = $rootScope.globals.currentUser.token;
$http.defaults.headers.common['aimm-id'] = $rootScope.globals.currentUser.id;
}
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
var clearenceLevel = toState.data.clearenceLevel;
var loggedIn = $rootScope.globals.currentUser;
if (clearenceLevel > 0 && !loggedIn) {
alert("redirecting");
return $state.go('login');
}
});
}
})();
I just can't have $state.go() working. The $on('$stateChangeStart'...); is working fine, and the alert is poping when trying to reach a protected state with no session. But the return $state.go('login'); doesnt work. It redirects to /app.
Thanks for your help.
Well, thanks to #Vanojx1, I found out adding e.preventDefault(); before the $state.go('login'); made it work. Still dont understand why though.
You need to execute the $state.go on main scope and not in a (angular) service or virtual scope created temporarily.
You can also solve the problem by wrapping it in $timeout or setTimeout which will register it in the browser loop to be executed after the current method run etc even with 0 milliseconds will do it, like.
$timeout(()=>{$state.go('xyz')},0)
or
setTimeout(()=>{$state.go('xyz')},0);
Related
If type the username or password once wrong and change manually the URL to my home GUI, I get access to it without any authentication.
I can't explain why :/
this is my app.js, where all the routing happens and a fiddle with my controller and my html data :
(function() {
'use strict';
// declare modules
angular.module('Authentication', []);
angular.module('Home', ['naif.base64', 'ngFileSaver']);
//dependecies of the module
angular.module('JMeterGui', ['Authentication','Home','ngRoute', 'ngCookies'])
//configure the module
.config(config)
//configure the start of the module
.run(run);
//dependencies of the config module
config.$inject = ['$routeProvider', '$locationProvider', '$qProvider'];
//configure routing depends on the actual URL
function config($routeProvider, $locationProvider, $qProvider) {
$routeProvider
.when('/', {
controller: 'HomeController',
templateUrl: 'modules/home/views/home.html'
})
.when('/login', {
controller: 'LoginController',
templateUrl: 'modules/authentication/views/login.html'
})
.otherwise({ redirectTo: '/login' });
}
//dependecies of the run module
run.$inject = ['$rootScope', '$location', '$cookies', '$http'];
function run($rootScope, $location, $cookies, $http) {
// keep user logged in after page refresh
$rootScope.globals = $cookies.getObject('globals') || {};
if ($rootScope.globals.currentUser) {
$http.defaults.headers.common['Authorization'] = 'Basic ' + $rootScope.globals.currentUser.authdata;
}
$rootScope.$on('$locationChangeStart', function (event, next, current) {
// redirect to login page if not logged in
var restrictedPage = $.inArray($location.path(), ['/login']) === -1;
var loggedIn = $rootScope.globals.currentUser;
if (restrictedPage && !loggedIn) {
$location.path('/login');
}
});
}
})()
my fiddle with controller and html
Anyone knows why ?
Try to add:
if (restrictedPage && !loggedIn) {
//Prevent default
event.preventDefault();
$location.path('/login');
}
When a user enters the state cloud, it checks if a current variable is found, and if it isn't, it redirects them to a different state. But for some reason, I get the following error on the redirect.
If I just go directly to /new, it does not give me the error. Only when the redirect occurs.
Does anyone know what the issue might be?
.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/cloud');
var billable = ['$rootScope', '$state', function ($rootScope, $state) {
if(!$rootScope.billable) $state.go('new');
}];
$stateProvider
.state('new', {
url: '/new',
views: { 'main': { templateUrl: 'pages/templates/new.html', controller: 'new' } },
})
.state('cloud', {
url: '/cloud',
views: { 'main': { templateUrl: 'pages/templates/cloud.html', controller: 'cloud' } },
onEnter: billable
})
})
Error: null is not an object (evaluating 'name')
updateView#http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js:3953:87
http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js:3924:21
$broadcast#http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js:14720:33
load#http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js:3678:32
http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js:3554:30
proceed#http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js:474:48
invoke#http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js:470:33
http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js:449:20
http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js:3557:46
forEach#http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js:331:24
resolveViews#http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js:3551:16
processQueue#http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js:13189:29
http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js:13205:39
$digest#http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js:14217:36
http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js:14440:33
completeOutstandingRequest#http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js:4905:15
http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js:5285:33
The way you have this configured, I don't believe any states have been defined yet because the application has not yet been bootstrapped. Additionally, route redirects like this are typically placed in the run method, not in the config.
You could pass billable (as a boolean or whatever you need it to be) in the params of the url and redirect based on that.
i.e.
// I'm assuming you're using UI-Router
.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/cloud');
$stateProvider
.state('new', {
url: '/new',
views: { 'main': { templateUrl: 'pages/templates/new.html', controller: 'new' } },
})
.state('cloud', {
url: '/cloud?billable',
views: { 'main': { templateUrl: 'pages/templates/cloud.html', controller: 'cloud' } },
})
}])
.run(['$rootScope', '$state', function($rootScope, $state) {
$rootScope.$on("$stateChangeStart", function(e, toState, toParams, fromState, fromParams) {
if (!toParams.billable) {
e.preventDefault();
$state.go('new');
}
});
}]);
My objective is to to send a token as Authorization header to each of the service calls in my application.
Here is my code
'use strict';
var properties = {};
angular.module('nbaportalUi', ['ngAnimate', 'ngCookies', 'ngTouch', 'ngSanitize',
'ngResource', 'ui.router', 'ui.bootstrap', 'uiSwitch'])
.run(['$rootScope', '$state', '$window', '$cookies', function ($rootScope, $state, $window, $cookies, $http) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams, options) {
$http.defaults.headers.common.Authorization = 'Bearer carmeloanthony' ;
});
}])
.config( function($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider
.otherwise('/home');
// note the 'abstract:true' state below - it can not get activated
// it is activated implicitly when one of its descendants are activated
$stateProvider
.state('app', {
abstract: true,
controller: 'MainCtrl',
templateUrl: 'app/main/main.html'
})
.state('app.overview', {
url: '/overview',
templateUrl: 'app/overview/summary.html',
controller: 'OverviewCtrl'
})
.state('loginPage', {
url: '/login',
templateUrl: 'app/login/login.html',
controller: 'LoginCtrl'
})
.state('errorPage', {
url: '/error404',
templateUrl: 'app/404.html'
});
})
.constant('ENV', {
'name': 'dev',
'apiEndpoint': 'https://api.blah.com/nba/v1/team/'
})
;
I am inserting $http.defaults.headers.common.Authorization = 'Bearer carmeloanthony' ; inside $stateChangeStart because it is called every time.
However when i attempt to this i get an error saying
angular.js:11706 TypeError: Cannot read property 'defaults' of undefined
at index.js:43
This error is refering to the following line of code -> $http.defaults.headers.common.Authorization = 'Bearer carmeloanthony' ;
However when i try to add the token as authorization adder outside stateChangeStart as follows it works:
'use strict';
var properties = {};
angular.module('nbaportalUi', ['ngAnimate', 'ngCookies', 'ngTouch', 'ngSanitize',
'ngResource', 'ui.router', 'ui.bootstrap', 'uiSwitch'])
.run(['$rootScope', '$state', '$window', '$cookies', function ($rootScope, $state, $window, $cookies) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams, options) {
});
}])
.config( function($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider
.otherwise('/home');
// note the 'abstract:true' state below - it can not get activated
// it is activated implicitly when one of its descendants are activated
$stateProvider
.state('app', {
abstract: true,
controller: 'MainCtrl',
templateUrl: 'app/main/main.html'
})
.state('app.overview', {
url: '/overview',
templateUrl: 'app/overview/summary.html',
controller: 'OverviewCtrl'
})
.state('loginPage', {
url: '/login',
templateUrl: 'app/login/login.html',
controller: 'LoginCtrl'
})
.state('errorPage', {
url: '/error404',
templateUrl: 'app/404.html'
});
})
.constant('ENV', {
'name': 'dev',
'apiEndpoint': 'https://api.blah.com/nba/v1/team/'
})
;
angular.module('nbaportalUi').run(function($http) {
$http.defaults.headers.common.Authorization = 'Bearer carmeloanthony' ;
});
I would prefer to get my first approach working. I appreciate any help I can get.
You have to include the $http service as following (your forgot to put in the array) :
.run(['$rootScope', '$state', '$window', '$cookies','$http', function ($rootScope, $state, $window, $cookies, $http) {
Inside my angularjs app. I have userService which has method for determination if user is loggedIn or not. userService.user.loggedIn()
now I want to use that service in order to implement secure pages, where I will redirect user upon this userService.user.loggedIn() statement.
my app.js looks like this
(function () {
"use strict";
var app = angular.module("myApp",
["common.services",
"$rootScope",
"ui.router",
"ui.mask",
"userService",
"ui.bootstrap"]);
app.config(["$stateProvider", "$urlRouterProvider",
function ($stateProvider, $urlRouterProvider, $rootScope) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state("index", {
url: "/",
templateUrl: "app/index.html",
})
// Home page /* SECURED */
.state("home", {
url: "/home",
templateUrl: "app/home/home.html",
controller: "HomeController as vm",
data: {
requiresLogin: true
}
})
// Login
.state("login", {
url: "/login",
templateUrl: "app/login/login.html",
controller: "LoginController as vm"
})
}]
);
$rootScope.$on('$stateChangeStart', function (e, to, userService) {
if (to.data && to.data.requiresLogin) {
if (!userService.user.loggedIn()) {
//token not found/not valid
e.preventDefault();
$location.path('/login');
}
}
});
}());
Inside console I'm getting
ReferenceError: $rootScope is not defined
$rootScope.$on('$stateChangeStart', function (e, to, appUserService,
$rootScope)...
It's not in the array of injectable:
Try this:
app.config(["$stateProvider", "$urlRouterProvider", "$rootScope",
function ($stateProvider, $urlRouterProvider, $rootScope) {
You can only place providers in config. So place your $rootScope.$on function in app controller.
(function () {
"use strict";
var app = angular.module("myApp",
["common.services",
"$rootScope",
"ui.router",
"ui.mask",
"userService",
"ui.bootstrap"]);
app.config(["$stateProvider", "$urlRouterProvider","$rootScope",
function ($stateProvider, $urlRouterProvider, $rootScope) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state("index", {
url: "/",
templateUrl: "app/index.html",
})
// Home page /* SECURED */
.state("home", {
url: "/home",
templateUrl: "app/home/home.html",
controller: "HomeController as vm",
data: {
requiresLogin: true
}
})
// Login
.state("login", {
url: "/login",
templateUrl: "app/login/login.html",
controller: "LoginController as vm"
})
}]
);
$rootScope.$on('$stateChangeStart', function (e, to, userService) {
if (to.data && to.data.requiresLogin) {
if (!userService.user.loggedIn()) {
//token not found/not valid
e.preventDefault();
$location.path('/login');
}
}
});
}());
You didn't post what the problem is, but I assume it is that nothing works. If so here is obvious problem with your code: you are trying use $rootScope as module dependency to application module.
Correct module definition must be:
angular.module("myApp", [
"common.services",
"ui.router",
"ui.mask",
"userService",
"ui.bootstrap"
])
I removed "$rootScope" from the list.
UPD. Closer look revealed another problem. You can't inject $rootScope into config block. Move it to the run:
app
.config([...])
.run(['$rootScope', function($rootScope) {
$rootScope.$on(...);
}];
you cant inject services (rootScope is service) in config only provides
but you can do it in app.run
Here's the calling order:
app.config() //only provides can be injected
app.run()
directive's compile functions (if they are found in the dom)
app.controller()
directive's link functions (again, if found)
app.run(["$stateProvider","$rootScope","userService",
function($stateProvider,$rootScope,userService){
$rootScope.$on('$stateChangeStart', function (e, toState, toParams, fromState, fromParams) {
if (toState.data && toState.data.requiresLogin) {
if (!userService.user.loggedIn()) {
//token not found/not valid
e.preventDefault();
$location.path('/login');
}
}
});
}]);