I have a problem with the provider in AngularJS.
I would like to in any view to check whether the user is logged on. If not then it should redirect to / login. On the console, there is no error. I do not know what is wrong.
var app= angular.module("app", ["ngRoute", "ngAnimate", "ngResource"]);
app.config(["$routeProvider", "$locationProvider", function($routeProvider, $locationProvider) {
var getItemNameById = function($route, $location, service, breadcrumbs, path) {
service.getItem($route.current.params.id).then(function(evt) {
if(evt.title) {
$route.routes[path].label = evt.title;
} else if(evt.name) {
$route.routes[path].label = evt.name;
}
breadcrumbs.generateBreadcrumbs();
}, function() {
$location.path("/404");
});
};
$routeProvider
.when("/", {
template: "",
label: "Home",
resolve: function($q, $location) {
alert("in resolve Home...");
var deferred = $q.defer();
if (!isLoggedIn) {
$location.path('/login');
}
deferred.resolve();
return deferred.promise;
}
})
.when("/patient", {
templateUrl: "patient.html",
label: "Patient",
resolve: function($q, $location) {
alert("in resolve Patient...");
var deferred = $q.defer();
if (!isLoggedIn) {
$location.path('/login');
}
deferred.resolve();
return deferred.promise;
}
})
.when("/doctor", {
templateUrl: "doctor.html",
controller: "DoctorController",
label: "Doctor",
resolve: function($q, $location) {
alert("in resolve Home...");
var deferred = $q.defer();
if (!isLoggedIn) {
$location.path('/login');
}
deferred.resolve();
return deferred.promise;
}
});
}]);
app.run(["$rootScope", "LoginService", function($rootScope, LoginService) {
LoginService.checkSession().then(function(response) {
$rootScope.isLoggedIn = response;
}, function(reject) {
$rootScope.isLoggedIn = reject;
});
}]);
why not enter into sections resolve (alert also does not show) on the home page?
best regards
I think you should set a event to route change ,something like this:
app.run(function($rootScope) {
$rootScope.$on("$routeChangeStart", function(event, nextRoute, currentRoute) {
if (nextRoute != null ) {
//Check session
}
});
});
Related
I want to remove exclamation marks from url state routing like my url is now
http://localhost:3000/#!/auth/register
i just want to remove this "!" marks from url after "#"
Is it possible to do? with mean.io
here is my app.js/system.js
'use strict';
//Setting up route
angular.module('mean').config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
// For unmatched routes:
//$urlRouterProvider.otherwise('/');
var checkLoggedin = function($q, $timeout, $http, $location) {
// Initialize a new promise
var deferred = $q.defer();
// Make an AJAX call to check if the user is logged in
$http.get('/loggedin').success(function(user) {
// Authenticated
if (user !== '0') $timeout(deferred.resolve);
// Not Authenticated
else {
$timeout(deferred.reject);
$location.url('/auth/login');
}
});
return deferred.promise;
};
// console.log($stateProvider);
// states for my app
$stateProvider
.state('tasks', {
url: '/kanban/:projectId/:projectSlug',
templateUrl: 'system/views/index.html',
controller: 'IndexController',
resolve: {
loggedin: checkLoggedin,
onEnter: function($stateParams,$state, $uibModal) {
if ( $stateParams.projectId != "" ) {
updateTopMenu('Kanban','task','#!/kanban/'+$stateParams.projectId+'/'+$stateParams.projectSlug);
updateTopMenu('Schedule','schedule','#!/schedule');
}
}
}
}).state('home',{
url:'/',
templateUrl: 'projects/views/index.html',
controller: 'ProjectController',
resolve:{
loggedin: checkLoggedin
}
}).state('taskEdit',{
url:'/kanban/:projectId/:projectSlug/:taskSlug',
templateUrl: 'system/views/index.html',
controller: 'IndexController',
resolve:{
loggedin: checkLoggedin
}
}).state('taskAdd',{
url: "/task/taskAdd",
onEnter: function($stateParams, $state, $uibModal) {
$uibModal.open({
templateUrl: "system/views/include/model.html",
resolve: {},
controller: function($scope, $state, itemService) {
/*
$scope.state = $state.current;
$scope.params = $stateParams;
$scope.item = itemService.get($stateParams.id);
*/
$scope.ok = function () {
$scope.$close('clicked ok');
};
$scope.dismiss = function () {
$scope.$dismiss('clicked cancel');
};
}
}).result.then(function (result) {
// $scope.$close
alert('result ->' + result);
}, function (result) {
// $scope.$dismiss
return $state.transitionTo("home");
alert('dismiss ->' + result);
}).finally(function () {
// handle finally
return $state.transitionTo("tasks");
});
}
});
}
]).config(['$locationProvider',
function($locationProvider) {
$locationProvider.hashPrefix('!');
}
]);
You can make some transformation on url with $urlRouterProvider.rule in your config function like this:
$urlRouterProvider.rule(function ($injector, $location) {
var path = $location.path(),
normalized = path.replace('!/', '');
if (path !== normalized) {
return normalized;
}
});
Not sure if this is the best way but it seems to work.
Inspired from: https://ui-router.github.io/docs/1.0.0-alpha.5/classes/url.urlrouterprovider.html
Issue: On Firebase login, I would like to redirect the user to a new page.I am trying to use $location.path() in my controller even I tried using $state.go(). But it seems to be no use. Also I am not getting any error in console.
Using Firebase signInWithEmailAndPassword method, Angularjs 1.5, ui-router and AngularFire.
login.service.js
var firebaseAuthObject = fbDbConn.auth();
function login(emailid, passwd) {
return firebaseAuthObject.signInWithEmailAndPassword(emailid, passwd);
}
login.controller.js
(function() {
'use strict';
angular
.controller('AuthController', AuthController);
AuthController.$inject = ['$scope', '$location', 'authService'];
function AuthController($scope, $location, authService) {
$scope.message = null;
$scope.error = null;
$scope.register = function() {
return authService.register($scope.email, $scope.password)
.then(function(userData) {
$scope.message = "User created with uid: " + userData.uid;
}).catch(function(error) {
$scope.error = error;console.log(error);
});
};
$scope.login = function() {
$scope.auth_error ="";
return authService.login($scope.email, $scope.password)
.then(function(authData) {
$location.path('/app/overview'); //$state.go('/app/overview');
}).catch(function(error) {console.log(error);
$scope.error = error;
$scope.auth_error = "Username or Password is wrong.";
});
};
$scope.logout = function() {console.clear();
authService.logout();
$location.path('/login');
};
}
})();
config.route.js
(function() {
'use strict';
angular
.module('singApp.login', ['ui.router','firebase'])
.config(configFunction)
.run(runFunction);
configFunction.$inject = ['$stateProvider'];
function configFunction($stateProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'app/modules/login/login.html'
})
}
runFunction.$inject = ['$location', 'authService', 'firebaseDataService', 'PROTECTED_PATHS'];
function runFunction($location, authService, firebaseDataService, PROTECTED_PATHS) {
authService.firebaseAuthObject.onAuthStateChanged(function(authData) {
if (!authData && pathIsProtected($location.path())) {
authService.logout();
$location.path('/login');
};
});
function pathIsProtected(path) {
return PROTECTED_PATHS.indexOf(path) !== -1;
}
}
})();
Thanks for help !!
first you should inject $state to your controller and use $state.go('stateName')
$state.go('/app/overview') will not work
you should use $state.go('stateName')
angular
.controller('AuthController', AuthController);
AuthController.$inject = ['$scope', '$location','$state', 'authService'];
function AuthController($scope, $location, $state,authService) {
$scope.message = null;
$scope.error = null;
$scope.register = function() {
return authService.register($scope.email, $scope.password)
.then(function(userData) {
$scope.message = "User created with uid: " + userData.uid;
}).catch(function(error) {
$scope.error = error;console.log(error);
});
};
$scope.login = function() {
$scope.auth_error ="";
return authService.login($scope.email, $scope.password)
.then(function(authData) {
$state.go('stateName');
}).catch(function(error) {console.log(error);
$scope.error = error;
$scope.auth_error = "Username or Password is wrong.";
});
};
$scope.logout = function() {console.clear();
authService.logout();
$location.path('/login');
};
}
})();
Just check the $state.go() method instead of $location
First inject the dependency '$state'
AuthController.$inject = ['$scope', '$state', 'authService'];
Check your routes.js file.
The below is a sample code.
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/profile");
$stateProvider
.state('login', {
url: '/',
templateUrl: 'login.html'
})
.state('app.overview', {
url: '/overview',
templateUrl: 'views/overview.html'
})
});
If everything correct then then you can use the below code for redirection.
$state.go('login');
I'm using the '$stateChangeSuccess' event to find out the route changes.
app.run(['$rootScope', '$state', '$stateParams', '$cookies', '$timeout',
function($rootScope, $state, $stateParams, $cookies, $timeout) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
$rootScope.$on('$stateChangeSuccess', function(event, nextRoute, toState) {
console.log(nextRoute.name);
// $state.go('login');
});
}
])
This question comes from another one: AngularJS - Determine if the view should be displayed by an ajax call result upon the route changes
As to my previous question, finally I came to this solution:
(function() {
'use strict';
angular.module("appClubS", ["appClubS.userModule", "appClubS.productModule", "clubsServices", "ngRoute", "ui.bootstrap"])
.config(routeConfigurator);
angular.module("appClubS")
.controller("checkLoginCtrl", checkLoginController);
checkLoginController.$inject = ['$scope', '$rootScope', '$location', 'userFactory'];
routeConfigurator.$inject = ['$routeProvider', '$locationProvider'];
function routeConfigurator($routeProvider, $locationProvider) {
$routeProvider.when("/home", {
templateUrl: "views/index.html"
});
// ...
// the routes that visitor cannot access before signing in
$routeProvider.when("/account-profile/my-redeem", {
templateUrl: "views/member_zone/my.redeem.html",
resolve: {
loggedin: ["$q", "userFactory", "$location", function checkPermit($q, userFactory, $location) {
var deferred = $q.defer();
var logStatus = userFactory.loggedin();
if (logStatus) {
deferred.resolve({
message: "Proceed to change route."
});
}
else {
deferred.reject({
message: "Redirect to the default page."
});
alert("Please Login First!");
$location.path("/login");
}
return deferred.promise;
}]
}
});
$routeProvider.when("/account-profile/my-survey", {
templateUrl: "views/member_zone/my.survey.html",
resolve: {
loggedin: ["$q", "userFactory", "$location", function checkPermit($q, userFactory, $location) {
var deferred = $q.defer();
var logStatus = userFactory.loggedin();
if (logStatus) {
deferred.resolve({
message: "Proceed to change route."
});
}
else {
deferred.reject({
message: "Redirect to the default page."
});
alert("Please Login First!");
$location.path("/login");
}
return deferred.promise;
}]
}
});
// ...
}
})();
However, I have repeated the same piece of code for each route I would like to forbid undesired access. So now my question is how to do it once for all. I have tried the code as below:
(function() {
'use strict';
angular.module("appClubS", ["appClubS.userModule", "appClubS.productModule", "clubsServices", "ngRoute", "ui.bootstrap"])
.config(routeConfigurator);
angular.module("appClubS")
.controller("checkLoginCtrl", checkLoginController);
checkLoginController.$inject = ['$scope', '$rootScope', '$location', 'userFactory'];
routeConfigurator.$inject = ['$routeProvider', '$locationProvider'];
function routeConfigurator($routeProvider, $locationProvider) {
$routeProvider.when("/home", {
templateUrl: "views/index.html"
});
// ...
// the routes that visitor cannot access before signing in
$routeProvider.when("/account-profile/my-redeem", {
templateUrl: "views/member_zone/my.redeem.html",
resolve: {
loggedin: ["$q", "userFactory", "$location", checkPermit]
}
});
$routeProvider.when("/account-profile/my-survey", {
templateUrl: "views/member_zone/my.survey.html",
resolve: {
loggedin: ["$q", "userFactory", "$location", checkPermit]
}
});
// ...
}
function checkPermit($q, userFactory, $location) {
var deferred = $q.defer();
var logStatus = userFactory.loggedin();
if (logStatus) {
deferred.resolve({
message: "Proceed to change route."
});
}
else {
deferred.reject({
message: "Redirect to the default page."
});
alert("Please Login First!");
$location.path("/login");
}
return deferred.promise;
}
})();
And it doesn't work, I got error saying: defer is not defined, something like that. Then I used a factory to wrap that piece of logic:
(function() {
'use strict';
angular.module("appClubS", ["appClubS.userModule", "appClubS.productModule", "clubsServices", "ngRoute", "ui.bootstrap"])
.config(routeConfigurator);
angular.module("appClubS")
.controller("checkLoginCtrl", checkLoginController)
.factory('checkPermit', checkPermitFactory);
checkLoginController.$inject = ['$scope', '$rootScope', '$location', 'userFactory'];
routeConfigurator.$inject = ['$routeProvider', '$locationProvider', 'checkPermit'];
checkPermitFactory.$inject = ['$q', '$location', 'userFactory'];
function routeConfigurator($routeProvider, $locationProvider, checkPermit) {
$routeProvider.when("/home", {
templateUrl: "views/index.html"
});
// ...
// the routes that visitor cannot access before signing in
$routeProvider.when("/account-profile/my-redeem", {
templateUrl: "views/member_zone/my.redeem.html",
resolve: {
loggedin: function (checkPermit) {
return checkPermit.checklogin();
}
}
});
$routeProvider.when("/account-profile/my-survey", {
templateUrl: "views/member_zone/my.survey.html",
resolve: {
loggedin: function (checkPermit) {
return checkPermit.checklogin();
}
}
});
// ...
}
function checkPermitFactory($q, userFactory, $location) {
function checklogin() {
var deferred = $q.defer();
var logStatus = userFactory.loggedin();
if (logStatus) {
deferred.resolve({ message: "Proceed to change route." });
}
else {
deferred.reject({ message: "Redirect to the default page." });
alert("Please Login First!");
$location.path("/login");
}
return deferred.promise;
}
var factory = {
checklogin: checklogin
};
return factory;
}
})();
And I got error saying that it could not find checkPermit provider, when investigating this problem, I realized that you just cannot inject an dependency on an stance of factory to routeConfigurator, so here I am supposed to use checkPermitProvider instead.
I am confused now.
Any help is appreciated. Thanks.
thank you all for the replies.
In the end, I found I can get it working in this way:
(function() {
'use strict';
angular.module("appClubS", ["appClubS.userModule", "appClubS.productModule", "clubsServices", "ngRoute", "ui.bootstrap"])
.config(routeConfigurator);
angular.module("appClubS")
.controller("checkLoginCtrl", ['$q', '$location', 'userFactory', function checkPermitFactory($q, userFactory, $location) {
function checklogin() {
var deferred = $q.defer();
var logStatus = userFactory.loggedin();
if (logStatus) {
deferred.resolve({ message: "Proceed to change route." });
}
else {
deferred.reject({ message: "Redirect to the default page." });
alert("Please Login First!");
$location.path("/login");
}
return deferred.promise;
}
var factory = {
checklogin: checklogin
};
return factory;
}])
.factory('checkPermit', checkPermitFactory);
checkLoginController.$inject = ['$scope', '$rootScope', '$location', 'userFactory'];
routeConfigurator.$inject = ['$routeProvider', '$locationProvider', 'checkPermit'];
function routeConfigurator($routeProvider, $locationProvider, checkPermit) {
$routeProvider.when("/home", {
templateUrl: "views/index.html"
});
// ...
// the routes that visitor cannot access before signing in
$routeProvider.when("/account-profile/my-redeem", {
templateUrl: "views/member_zone/my.redeem.html",
resolve: {
loggedin: function (checkPermit) {
return checkPermit.checklogin();
}
}
});
$routeProvider.when("/account-profile/my-survey", {
templateUrl: "views/member_zone/my.survey.html",
resolve: {
loggedin: function (checkPermit) {
return checkPermit.checklogin();
}
}
});
// ...
}
})();
I used $inject property to specify the dependencies just because that was suggested in the section 'Manually Identify Dependencies' in this article: https://github.com/johnpapa/angularjs-styleguide#manually-identify-dependencies.
And honestly I don't quite understand how does $inject work exactly though; I just got the concerns behind that. So this problem has been solved, but I don't know the difference between the two ways of defining a controller and declaring there dependencies.
I would like to before the advent of the home page if the user is not logged in is to move it to the login page.
At this moment Main page appears (half a second) and then loads the login page.
var app = angular.module("app", ["ngRoute", "ngAnimate"])
.constant('ACCESS_LEVELS', {
guest: 1,
user: 2,
admin: 3
});
app.config(["$routeProvider", "$locationProvider", "ACCESS_LEVELS", function($routeProvider, $locationProvider, ACCESS_LEVELS) {
$routeProvider
.when("/", {
template: "",
access_level: ACCESS_LEVELS.user
});
}]);
app.run(["$rootScope", "$window", "LoginService", function($rootScope, $window, LoginService) {
$rootScope.$on('$routeChangeStart', function(evt, next, curr) {
if(next.access_level !== undefined) {
LoginService.checkSession().then(function(response) {
$rootScope.isLoggedIn = response;
if(!response) {
$window.location.href = '/login.html';
}
}, function(error) {
$rootScope.isLoggedIn = error;
});
}
})
}]);
Is there a way to angular done without flash home page?
regards
You can use the ‘resolve’ property of the routeProvider.
From the docs:
resolve - An optional map of dependencies which should be >injected into the controller. If any of these dependencies are promises, the router will wait >for them all to be resolved or one to be rejected before the controller is instantiated.
https://docs.angularjs.org/api/ngRoute/provider/$routeProvider
So your routeProvider could look as follows, with the session promise specified as a dependency of your home route. You would then need to inject the session into the home controller.
$routeProvider
.when("/", {
template: "",
access_level: ACCESS_LEVELS.user,
controller: ‘homeCtrl’,
resolve: {
session: function(LoginService) {
return LoginService.checkSession();
}
}
});
A good blog post: http://blog.brunoscopelliti.com/show-route-only-after-all-promises-are-resolved
My current code:
in main app.js:
var app = angular.module("app", ["ngRoute", "ngAnimate", "ngResource"])
.constant('ACCESS_LEVELS', {
guest: 1,
user: 2,
admin: 3
});
besecure.config(["$routeProvider", "$locationProvider", "ACCESS_LEVELS", function($routeProvider, $locationProvider, ACCESS_LEVELS) {
$routeProvider
.when("/", {
template: "",
label: "Home",
access_level: ACCESS_LEVELS.user,
resolve: {
session: function(LoginService) {
return LoginService.checkSession();
}
}
});
}]);
app.run(["$rootScope", "$window", "$location", "LoginService", function($rootScope, $window, $location, LoginService) {
$rootScope.loadingView = false;
$rootScope.$on('$routeChangeStart', function(evt, curr, prev) {
if(curr.access_level !== undefined) {
if(curr.$$route && curr.$$route.resolve) {
$rootScope.loadingView = true;
} else {
$window.location.href = '/login.html';
}
}
})
}]);
Service:
app.factory("LoginService", function($resource, $q) {
var LoginService,
Login = $resource("/auth/login");
LoginService = {
checkSession: function() {
var deferred = $q.defer();
Login.get().$promise.then(function(response) {
deferred.resolve(response.result);
}, function(error) {
deferred.reject(false);
});
return deferred.promise;
}
};
return LoginService;
});
Service is OK.
and not work redirecting
I've a problem with 2 resolves, one for each controller.
http://jsfiddle.net/pvivera/RhAHy/
var app = angular.module('testApp', [], function($routeProvider){
$routeProvider.when('/', {
template: 'Home {{model}}',
controller: 'HomeCtrl',
resolve: HomeCtrl.resolve
})
.when('/About', {
template: 'About {{model}}',
controller: 'AboutCtrl',
resolve: AboutCtrl.resolve
});
});
var HomeCtrl = app.controller('HomeCtrl', function($scope, HomeCtrlData){
$scope.model = HomeCtrlData;
});
HomeCtrl.resolve = {
HomeCtrlData: function($q, $timeout){
var deferred = $q.defer();
$timeout(function(){
return deferred.resolve('AboutCtrlResolver');
}, 2000);
return deferred.promise;
}
};
var AboutCtrl = app.controller('AboutCtrl', function($scope, AboutCtrlData){
$scope.model = AboutCtrlData;
});
AboutCtrl.resolve = {
AboutCtrlData: function($q, $timeout){
var deferred = $q.defer();
$timeout(function(){
return deferred.resolve('AboutCtrlResolver');
}, 2000);
return deferred.promise;
}
};
In the jsfiddler script, when the HomeCtrl want to resolve HomeCtrlData I receive this error Unknown provider: HomeCtrlDataProvider <- HomeCtrlData
If I change HomeCtrlData to AboutCtrlData in the HomeCtrl everything works, it seems that the only resolve that is assigned is AboutCtrl.resolve
Any idea?
The problem here is that app.controller() doesn't return the controller, it returns your application module. So you're assigning app.resolve twice, which is why it doesn't work for one of them.
I would suggest that you inline the resolve function like this instead:
var app = angular.module('testApp', [], function($routeProvider){
$routeProvider.when('/', {
template: 'Home {{model}}',
controller: 'HomeCtrl',
resolve: {
HomeCtrlData: function($q, $timeout) {
var deferred = $q.defer();
$timeout(function(){
return deferred.resolve('HomeCtrlData');
}, 2000);
return deferred.promise;
}
}
})
.when('/About', {
template: 'About {{model}}',
controller: 'AboutCtrl',
resolve: {
AboutCtrlData: function($q, $timeout) {
var deferred = $q.defer();
$timeout(function(){
return deferred.resolve('AboutCtrlData');
}, 2000);
return deferred.promise;
}
}
});
});