how to delay loading the page in route AngularJS? - angularjs

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

Related

Unable to redirect to new page using $location.path with Firebase login

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');
});
}
])

Unknown provider: currentAuthProvider <- currentAuth on AngularFire v2 Firebase v3

I am trying to make user login and go on from / route in my angularfire app. But, somehow I got Unknown Provider Error while I am in MainController.
Here is my work;
var app = angular.module("myApp", ['firebase', 'ngRoute']);
This the factory of firebaseAuth.
app.factory("Auth", ["$firebaseAuth",
function($firebaseAuth) {
return $firebaseAuth();
}
]);
This is from authenticating with routers angularfire tutorial.
app.run(["$rootScope", "$location", function($rootScope, $location) {
$rootScope.$on("$routeChangeError", function(event, next, previous, error) {
if (error === "AUTH_REQUIRED") {
$location.path("/login");
}
});
}]);
app.config(["$routeProvider", function($routeProvider) {
$routeProvider.when("/login", {
controller: "LoginController",
templateUrl: "views/login.html",
resolve: {
"currentAuth": ["Auth", function(Auth) {
return Auth.$waitForSignIn();
}]
}
}).when("/", {
controller: "MainController",
templateUrl: "views/home.html",
resolve: {
"currentAuth": ["Auth", function(Auth) {
return Auth.$requireSignIn();
}]
}
});
}]);
In the login page I can sign in via google pop up and I can see the cookie in the browser.
app.controller("LoginController", ["$scope", "currentAuth", "Auth", function($scope, currentAuth, Auth) {
$scope.auth = Auth;
$scope.auth.$onAuthStateChanged(function(firebaseUser) {
$scope.firebaseUser = firebaseUser;
});
}]);
When I open "/" path, it fails and creating error like this
app.controller("MainController", [ "$scope", "$location", "$firebaseArray", "currentAuth", function($scope, $location, $firebaseArray, currentAuth) {
var ref = firebase.database().ref();
if (currentAuth == undefined || currentAuth == null) {
$location.path('/login');
}
}]);
Is there something wrong that I miss ?
Thank you.

AngularJS - Hook Routes Changing and Centralize the logic upon that

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.

forwarding in section resolve by RouteProvider to another view

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

AngularJS working with $location.path and ngRoute

I have this $location.path redirection:
myapp.controller('registerCtrl', function ($scope, $location, regService) {
$scope.register = function() {
$('#regbutton').prop('disabled','disabled');
regService.createUser($scope.email, $scope.password, function(id) {
if (id) {
$('#register').modal('hide');
$location.path('/account');
}
});
}
})
When the redirection occurs it redirects the user to http://myapp.com/#/account
Now I want to display a different template to show the user account. So I'm trying to use ngRoute but cannot get it to work properly..
myapp.config(['$routeProvider', '$locationProvider', '$provide',
function ($routeProvider, $locationProvider, $provide) {
console.log('in');
$provide.decorator('$sniffer', function($delegate) {
$delegate.history = false;
return $delegate;
});
$routeProvider.
when('/account', {
templateUrl: 'account.html',
resolve: {
// I will cause a 1 second delay
delay: function ($q, $timeout) {
console.log('in resolve');
var delay = $q.defer();
$timeout(delay.resolve, 1000);
return delay.promise;
}
}
});
$locationProvider
.html5Mode(true)
.hashPrefix('');
}]);
The route you should be using in the configuration when() function is /account

Resources