Waiting for $ rootScope to resolve in Angular before page loads

So, I came across this problem when I use ngView and I have a navigation bar that is so static:

<div ng-include="'views/nav.html'" ng-controller="NavCtrl"></div> <div class="container-fluid" ng-view=""></div> 

This nav.html navigation bar displays a specific set of functions (Login, Register) if the user is logged out (using ng-show) and other menu options if the user is logged in. Due to the heavy use of the current user, I put this information in $ rootScope as follows: $rootScope.currentUser - returns the user object, and $rootScope.signedIn - returns the boolean value.

Basically, I want to postpone navigation from loading until $rootScope.signedIn is loaded and true or false, and $rootScope.currentUser is an object or undefined.

I tried communicating with making promises in my app.config routes, but I'm not sure how I can return a promise to a constant viewing state.

Any help is appreciated.

Edit

Here is the service in which I broadcast my login. This is triggered at any time when the user authenticates / logs in or logs out at any time:

  var authClient = new FirebaseSimpleLogin(refDownload, function(error, user) { if (error) { incorrectLogin(error.code); } if (user) { // user authenticated $rootScope.$broadcast('login'); correctLogin(user.id); } else { // user is logged out $rootScope.$broadcast('logout'); } }); 

This service is entered into the NavCtrl controller as follows:

  $scope.isHidden = true; $scope.$on('login', function() { console.log('login broadcast'); $scope.isHidden = false; }); $scope.$on('logout', function() { console.log('broadcast logout'); $scope.isHidden = true; }); 

The template for this controller is nav.html, which looks like this:

 <div class="col-xs-4 centered" id="nav-hover" ng-show="isHidden"> <ul class="nav navbar-nav"> <li id="nav-login"><a ng-href="#/login"><span class="glyphicon glyphicon-log-in">&nbsp;Login</span></a></li> </ul> </div> <div class="col-xs-4 centered" id="nav-hover" ng-show="isHidden"> <ul class="nav navbar-nav"> <li id="nav-login"><a ng-href="#/register"><span class="glyphicon glyphicon-edit">&nbsp;Register</span></a></li> </ul> </div> <div class="col-xs-2 centered" id="nav-hover"> <ul class="nav navbar-nav" ng-hide="isHidden"> <li ng-class="{{ chatCat.active }}"><a ng-href="{{ chatCat.url }}"><span class="{{ chatCat.icon }}"></span></a></li> </ul> </div> 

Again, this view is tied to NavCtrl. When registering users, I use AuthCtrl as follows:

  $scope.login = function() { if ($scope.user !== undefined) { Auth.login($scope.user); $location.path('/dexter'); } else { console.log('nothing entered'); } }; 

When I try to log in, the navigation view is not updated with the new values, although the broadcast starts from the service with "logged in".

Auth Service:

 'use strict'; app.factory('Auth', function($rootScope, $location, $firebase, $firebaseSimpleLogin, firebaseUrl) { var refDownload = new Firebase(firebaseUrl + 'housemates'); var sync = $firebase(refDownload); var ref = sync.$asObject(); var authClient = new FirebaseSimpleLogin(refDownload, function(error, user) { if (error) { incorrectLogin(error.code); } if (user) { // 1 // user authenticated correctLogin(user.id); } else { // user is logged out // $rootScope.signedIn = false; } }); var Auth = { housemates: ref, changeColor: function(color) { var id = $rootScope.currentUser.id.toString(); refDownload.child(id).update({ color: color }); $rootScope.currentUser.color = color; }, create: function(authUser, usr) { refDownload.child(authUser.id).set({ initials: usr.initials, email: authUser.email, password: usr.password, color: 'Blue', id: authUser.id, uid: authUser.uid, rememberMe: true, }); }, // 3 findById: function(id) { refDownload.on('value', function(snapshot) { var userObject = snapshot.val(); // 4 - sets currentUser //$rootScope.currentUser = userObject[id]; var currentUser = userObject[id]; Auth.setUser(currentUser); // $rootScope.signedIn = true; }, function (error) { console.log(error); }); }, login: function(user) { authClient.login('password', { email: user.email, password: user.password, rememberMe: true }); }, logout: function() { delete $rootScope.currentUser; delete $rootScope.signedIn; delete $rootScope.error; return authClient.logout(); }, register: function(user) { var userSimple = user; authClient.createUser(user.email, user.password, function(error, user) { if(!error) { var userComplex = user; Auth.login(userSimple); Auth.create(userComplex, userSimple); return user; } else { console.log(error); } }); }, setUser: function(aUser) { console.log('setuser ran'); $rootScope.currentUser = aUser; console.log('setUser: ' + $rootScope.currentUser); }, isLoggedIn: function() { console.log($rootScope.currentUser); return ($rootScope.currentUser) ? $rootScope.currentUser : false; }, }; // 2 function correctLogin(id) { Auth.findById(id); } function incorrectLogin(error) { alert(error); $rootScope.error = error; } return Auth; }); 
+6
source share
3 answers

With a little $ rootScope. $ broadcast and ng-hide on the menu can easily be done. See plunker

html:

 <!DOCTYPE html> <html ng-app="plunker"> <head> <meta charset="utf-8" /> <title>AngularJS Plunker</title> <script>document.write('<base href="' + document.location + '" />');</script> <link rel="stylesheet" href="style.css" /> <script data-require=" angular.js@1.2.x " src="https://code.angularjs.org/1.2.25/angular.js" data-semver="1.2.25"></script> <script src="app.js"></script> </head> <body ng-controller="MainCtrl"> <div ng-include="'nav.html'" ng-controller="NavCtrl" ng-hide="isHidden"></div> <button class="btn" ng-click="login()">Login</button> <button class="btn" ng-click="logout()">Logout</button> </body> </html> 

javascript:

 var app = angular.module('plunker', []); app.controller('MainCtrl', function($scope, $rootScope) { $scope.login = function() { $rootScope.$broadcast("login"); } $scope.logout = function() { $rootScope.$broadcast("logout"); } }); app.controller('NavCtrl', function($scope) { $scope.isHidden = true; $scope.$on('login', function() { console.log("logged in"); $scope.isHidden = false; }); $scope.$on('logout', function() { console.log("logged out"); $scope.isHidden = true; }); }); 
+6
source

OK, if the method I suggested does not work for you, here is the second possible solution ( plunker )

The main idea is to have a service (in this case a factory) in which you set the name of the user registered in the log, and then use $ watch in the navigation controller to view changes in the authentication status in the service. And the code:

 <!DOCTYPE html> <html ng-app="plunker"> <head> <meta charset="utf-8" /> <title>AngularJS Plunker</title> <script>document.write('<base href="' + document.location + '" />');</script> <link rel="stylesheet" href="style.css" /> <script data-require=" angular.js@1.2.x " src="https://code.angularjs.org/1.2.25/angular.js" data-semver="1.2.25"></script> <script src="app.js"></script> <script src="Auth.js"></script> </head> <body ng-controller="MainCtrl"> <div ng-include="'nav.html'" ng-controller="NavCtrl" ng-hide="isHidden"></div> <button class="btn" ng-click="login()">Login</button> <button class="btn" ng-click="logout()">Logout</button> </body> </html> 

javascript:

 var app = angular.module('plunker', []); app.controller('MainCtrl', function($scope, $rootScope, Auth) { $scope.login = function() { var user = "iris" Auth.setUser(user); } $scope.logout = function() { Auth.setUser(null); } }); app.controller('NavCtrl', function($scope, Auth) { $scope.isHidden = true; $scope.$watch(Auth.isLoggedIn, function (value, oldValue) { console.log("authentication changed"); if(!value && oldValue) { console.log("logged out"); $scope.isHidden = true; } if(value) { console.log("logged in"); $scope.isHidden = false; } }, true); }); 

and service:

 app.factory('Auth', function() { var user; return { setUser: function(aUser) { user = aUser; }, isLoggedIn: function() { console.log(user); return (user) ? user : false; } } }) 
+1
source

@zszep $ broadcast answer solved the problem with one caveat. It was necessary to add $scope.$apply() after each of the $ scope.isHidden commands in NavCtrl. This made me refresh the page and refresh Nav.

0
source

Source: https://habr.com/ru/post/976210/


All Articles