angularjs ng-show: show menu after successful login - javascript

I'm trying to show the navigation bar once the user logs in successfully. but the navigation-bar is still hidden even after the user logs in.
here is a part of the index.html
<header id="Header1" data-ng-controller="navigationController">
<!-- Navigation bar -->
<nav class="navbar navbar-inverse" id="nav1" ng-hide="isConnected">
<div class="collapse navbar-collapse">
<ul id="Ul1" class="nav navbar-nav" style="color: white; font-weight: bolder; font-family: Arial; border-radius: 5px;">
<!-- <li class="nav navbar-brand" id="Li1" style="padding: 0px 0px 0px 0px;">
<img src="favicon.ico" height="20" width="20" />
</li>-->
<li id="Li2" data-ng-class="{'active':isActive('/home')}">
<a data-original-title="Home page." class="disable-click" href="#/home">Home</a>
</li>
<li data-ng-class="{'active':isActive('/demo')}">
<a data-original-title="Demonstration page." class="disable-click" href="#/demo">Demonstration</a>
</li>
</ul>
</div>
</nav>
</header>
the controller navigationController.js is
'use strict';
app.controller('navigationController',
function ($scope, $location, $rootScope, AuthenticationService) {
debugger;
$scope.isActive = function (path) {
return $location.path().substr(0, path.length) == path;
};
$scope.isConnected = !($rootScope.globals.currentUser);
console.log($scope.isConnected);
});
i store the current user in this service
service.SetCredentials = function (username, password) {
var authdata = Base64.encode(username + ':' + password);
$rootScope.globals = {
currentUser: {
username: username,
authdata: authdata
}
};
$http.defaults.headers.common['Authorization'] = 'Basic ' + authdata;
$cookieStore.put('globals', $rootScope.globals);
};
the binding is not working after the login, except when i refresh the menu is shown (when the cookie has became full). any solution please

Your isConnected property is only evaluated once when the controller is instantiated. When the user logs in there is nothing to re-evaluate isConnected
You could set up a watch like this to have it re-evaluate:
'use strict';
app.controller('navigationController',
function ($scope, $location, $rootScope, AuthenticationService) {
debugger;
$scope.isActive = function (path) {
return $location.path().substr(0, path.length) == path;
};
$rootScope.$watch('globals', function(newVal, oldVal) {
$scope.isConnected = !($rootScope.globals.currentUser);
}, true);
});
note it might be possible you can add the watch directly to $scope instead of $rootScope as the globals property should be inherited prototypically, though I haven't tested this to verify

Try this
'use strict';
app.controller('navigationController',
function ($scope, $location, $rootScope, AuthenticationService) {
...
$scope.isConnected = function() {
return !($rootScope.globals.currentUser);
};
});
And do not change ng-hide value to ng-hide="isConnected()", keep it as ng-hide="isConnected"
<nav class="navbar navbar-inverse" id="nav1" ng-hide="isConnected">
...

Related

Displaying username after login with angular

I'm playing around with AngularJS and trying to build a very simple app for learning purposes, but i've ran into a problem.
I'm using Kinvey BAAS. So, this is what I'm trying to do:
I have a login.controller.js, which looks like this (skipping the module registration and the config parts...):
`
.controller('LoginController', [
'$scope',
'$location',
'users',
function ($scope, $rootScope, $location, users) {
$scope.login = function login() {
users.login($scope.user)
.then(function (loggedInUser) {
$location.path('/home');
console.log(loggedInUser);
}, function (error) {
console.log(error);
});
}
}
])
The idea is simple. Use a service to log the user in. Then, redirect him to the homepage (/home).
The authentication service looks like this (users.js):
`
.factory('users', [
'$http',
'$q',
'$cookies',
'$location',
'BASE_URL',
'APP_KEY',
'APP_SECRET',
function ($http, $q, $cookies, $location, BASE_URL, APP_KEY, APP_SECRET) {
var user = undefined;
function login(user) {
var deferred = $q.defer();
// Get the user information.
$http.post(BASE_URL + 'user/' + APP_KEY + '/login', {
username: user.username,
password: user.password
})
.then(function (response) {
_preserveUserData(response.data);
deferred.resolve(response);
}, function (error) {
deferred.reject(error);
});
return deferred.promise;
}
function _preserveUserData(data) {
var authToken = data._kmd.authtoken;
$cookies.put('authToken', authToken);
user = data;
}
function isLogged() {
if !! (user || $cookies.get('authToken'));
}
function getLoggedUser() {
var deferred = $q.defer();
if (user) {
deferred.resolve(user);
} else if ($cookies.get('authToken')) {
var authToken = $cookies.get('authToken');
$http.defaults.headers.common.Authorization = 'Kinvey ' + authToken;
$http.get(BASE_URL + 'user/' + APP_KEY + '/_me')
.then(function (response) {
user = response.data;
deferred.resolve(response);
}, function (error) {
deferred.reject(error);
});
} else {
deferred.reject('No logged user.');
}
return deferred.promise;
}
return {
login: login,
isLogged: isLogged,
getLoggedUser: getLoggedUser
};
}
]);
I also have a main controller (main.controller.js). The MainController wraps the whole content with a div (), for binding to the scope some global stuff...like the currently logged user.
`
.controller('MainController', [
'APP_TITLE',
'$scope',
'users',
function (APP_TITLE, $scope, users) {
// A place to store some more-global stuff.
$scope.appTitle = APP_TITLE;
$scope.user = undefined;
if (users.isLogged()) {
users.getLoggedUser()
.then(function (loggedUser) {
$scope.user = loggedUser.data;
}, function (error) {
console.log(error);
});
}
}
])
Now, this is the index.html (where the Main controller and the ng-view are):
<body>
<div ng-controller="MainController" ng-cloak>
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#!/">{{appTitle}}</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li>Home</li>
<li>Favorites</li>
<li>Users</li>
</ul>
<ul class="nav navbar-nav navbar-right" ng-if="user">
<li class="dropdown">
{{user.username}}<span class="caret"></span>
<ul class="dropdown-menu">
<li>Links</li>
<li>Edit Profile</li>
<li role="separator" class="divider"></li>
<li>Logout</li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please upgrade your browser to improve your experience.</p>
<![endif]-->
<div ng-view>
</div>
</div>
And this is the home.html (where the username should be displayed):
<div class="container">
<h2>Hello, <span ng-if="user">{{user.username}}</span></h2>
</div>
The thing is that, when the user is logged, I save a cookie and redirect the logged user...but the MainController doesn't register the logged in user (it never enters the if (users.isLogged()) part). I have to refresh to see the username of the user.
Any guidance on how to solve this problem will be handy. Also code quality and overall code-improvement suggestions will be also highly appreciated.
Thanks in advance!
Borislav.
users should be a service, not a factory... a service will create a single shared instance, a factory is a new instance for each controller.

AngularJS and Bootstrap tab behavior not working

So here is my code for my view:
<ul class="nav nav-pills" id="my-pill">
<li class="active"><a href="#tab0" data-toggle="tab">Tools
Home</a></li>
<li>Fair Trade Judge</li>
<li>Awards</li>
<li>Draft Buddy</li>
<li>Add A League</li>
<li>Insult Generator</li>
<li>League Poll</li>
<li>Smart Rankings</li>
<li>Composite Rankings</li>
<li><a href="#tab9" data-toggle="tab">Waiver Wire Pickup
Aid</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab0">
<div class="row">
<div class="col-md-12">
<h2>Tool Descriptions</h2>
<h3>Fair Trade Judge</h3>
<p>This tool will help you decide whether or not a proposed
trade is fair</p>
<h3>Awards</h3>
<p>Weekly awards given out to teams who have the best, and
worst weeks in the league</p>
<h3>Draft Buddy</h3>
<p>Use this tool to aid you during your big draft day</p>
<h3>Add A League</h3>
<p>This isn't really a tool, and doesn't fit on the
dashboard</p>
<h3>Insult Generator</h3>
<p>Let our team analysis algorithm pick apart any team in
your league with relevant insults</p>
<h3>League Poll</h3>
<p>Rank every team in your league on a weekly basis. Overall
rankings will be calculated based on the poll</p>
<h3>Smart Rankings</h3>
<p>This tool ranks every team in your league based on
complex rankings algorithm, that factors in more than just your
W-L-T record</p>
<h3>Composite Rankings</h3>
<p>Ever wonder what your record would be if you played every
team every week instead of the head to head match-up style?
This tool will tell you what your overall record would be</p>
<h3>Waiver Wire Pickup Aid</h3>
<p>See who our analysis of your team determines you should
pick up off of the waiver wire this week</p>
</div>
</div>
</div>
<div class="tab-pane" id="tab1" >
<h2>Select the teams that are going to do a trade, then
select the players</h2>
<div ng-controller="FTJController" class="teamWrapper">
<div class="col-md-6 team" style="float: left;">
{{list1}} <select ng-model="selectedTeam1"
ng-options="item as item.teamName for item in teams track by item.teamID"
ng-change="getRoster1(selectedTeam1)">
<option value="">Team 1</option>
</select>
<table class="table-striped" style="width: 100%">
<tr>
<td></td>
<td>Name</td>
<td>Position</td>
<td>NFLTeamName</td>
<td>InjuryCode</td>
</tr>
<tr ng-repeat="player1 in roster1">
<td><input type="radio" ng-value="{{player1.PlayerID}}"
ng-model="selected1" ng-change="addID1(selected1)"
name="selected1" /></td>
<td>{{player1.Name}}</td>
<td>{{player1.Position}}</td>
<td>{{player1.NFLTeamName}}</td>
<td>{{player1.InjuryCode}}</td>
</tr>
</table>
</div>
<div class="col-md-offset-6 team">
{{list2}} <select ng-model="selectedTeam2"
ng-options="item as item.teamName for item in teams track by item.teamID"
ng-change="getRoster2(selectedTeam2)">
<option value="">Team 2</option>
</select>
<table class="table-striped" style="width: 100%">
<tr>
<td></td>
<td>Name</td>
<td>Position</td>
<td>NFLTeamName</td>
<td>InjuryCode</td>
</tr>
<tr ng-repeat="player2 in roster2">
<td><input type="radio" ng-value="{{player2.PlayerID}}"
ng-model="selected2" ng-change="addID2(selected2)"
name="selected2" /></td>
<td>{{player2.Name}}</td>
<td>{{player2.Position}}</td>
<td>{{player2.NFLTeamName}}</td>
<td>{{player2.InjuryCode}}</td>
</tr>
</table>
</div>
<br />
<div class="button">
<input type="button" value="compare players"
ng-click="comparePlayers()" />
<div>Is this trade fair? {{FTJ}}</div>
</div>
</div>
</div>
Whenever I try to click on one of the tabs, instead of loading the data, it will redirect me to my login page. I don't want any redirection, since all the data I need loaded after login. If I change the class of tab1 to active, I get the data behavior I want, so I think it's an issue with Bootstrap. Any ideas?
EDIT: Here is my controller file (the calls to API are working fine)
HomeController.$inject = ['UserService', '$rootScope'];
function HomeController(UserService, $rootScope) {
var vm = this;
vm.user = null;
vm.allUsers = [];
vm.deleteUser = deleteUser;
initController();
function initController() {
loadCurrentUser();
}
function loadCurrentUser() {
UserService.GetByEmail($rootScope.globals.currentUser.email)
.then(function (user) {
vm.user = user.data;
});
}
function deleteUser(id) {
UserService.Delete(id)
.then(function () {
loadAllUsers();
});
}
}
FTJController.$inject = ['$scope', '$http'];
function FTJController($scope, $http) {
$scope.list1 = 'Select Team 1';
$scope.list2 = 'Select Team 2';
//$scope.selectedTeam = null;
$scope.teams = [];
$scope.players1 = [];
$scope.players2 = [];
$scope.roster1 = null;
$scope.roster2 = null;
$http({
method: 'GET',
url: './rest/LeagueTeams?LeagueID=1682132'
}).success(function (result) {
$scope.teams = result;
});
console.log("in controller");
$scope.getRoster1 = function(selectedTeam){
console.log("in getRoster with teamID = " + selectedTeam.teamID);
$http({
method: 'GET',
url: './rest/Roster?LeagueID=1682132&TeamID=' +selectedTeam.teamID + '&Week=1&Year=2015'
}).then(function (result){
$scope.roster1 = result.data;
});
}
//duplicating for now, should change to use the same method for both rosters
$scope.getRoster2 = function(selectedTeam){
console.log("in getRoster with teamID = " + selectedTeam.teamID);
$http({
method: 'GET',
url: './rest/Roster?LeagueID=1682132&TeamID=' +selectedTeam.teamID + '&Week=1&Year=2015'
}).then(function (result){
$scope.roster2 = result.data;
});
}
$scope.comparePlayers = function(){
console.log("testingsss");
console.log($scope.players1);
console.log($scope.players2);
console.log('call: ./rest/FTJ?PlayerID1=' + $scope.players1 + '&PlayerID2=' + $scope.players1);
console.log('Is $scope.players1 ' + ($scope.players1) + ' > $scope.players2 ' + $scope.players1 + ' ?');
console.log('comparison');
console.log($scope.players1 > $scope.players2);
$http({
method: 'GET',
url: './rest/FTJ?PlayerID1=' + $scope.players1 + '&PlayerID2=' + $scope.players2
}).then(function (result){
console.log('result.data');
console.log(result.data);
if (result.data){
$scope.FTJ = "Hell yea";
} else {
$scope.FTJ = "f no";
}
});
};
$scope.addID1 = function(s){
$scope.players1 = s;
console.log($scope.players1);
};
$scope.addID2 = function(s){
$scope.players2 = s;
console.log($scope.players2);
};
}
And here is my app.js file with the routing:
(function () {
'use strict';
angular
.module('app', ['ngRoute', 'ngCookies'])
.config(config)
.run(run);
config.$inject = ['$routeProvider', '$locationProvider'];
function config($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
controller: 'HomeController',
templateUrl: 'home/home.view.html/',
controllerAs: 'vm'
})
.when('/login', {
controller: 'LoginController',
templateUrl: 'login/login.view.html',
controllerAs: 'vm'
})
.when('/register', {
controller: 'RegisterController',
templateUrl: 'register/register.view.html',
controllerAs: 'vm'
})
.otherwise({ redirectTo: '/login' });
}
run.$inject = ['$rootScope', '$location', '$cookieStore', '$http'];
function run($rootScope, $location, $cookieStore, $http) {
// keep user logged in after page refresh
$rootScope.globals = $cookieStore.get('globals') || {};
if ($rootScope.globals.currentUser) {
$http.defaults.headers.common['Authorization'] = 'Basic ' + $rootScope.globals.currentUser.authdata; // jshint ignore:line
}
$rootScope.$on('$locationChangeStart', function (event, next, current) {
// redirect to login page if not logged in and trying to access a restricted page
var restrictedPage = $.inArray($location.path(), ['/login', '/register']) === -1;
var loggedIn = $rootScope.globals.currentUser;
if (restrictedPage && !loggedIn) {
$location.path('/login');
}
});
}
})();
How do I fix the routing so that when I click on tab1, it will just show the data and move to that tab instead of redirecting to login? Thanks!
It happens because of angular routing...
You can just add to every anchor tag the following attribute
target="_self"
For example: <li>Fair Trade Judge</li>
Hope it resolves it.
You can use data-target="#tab1" instead of href="#tab1"
Angular router is routing to #tab1 when you click on the link. Since there is no such route defined and login screen is the default route, it must be displaying the login screen.
you could use angular-ui to get bootstrap work easily with angular.
Your default page because there is no defined route to be found.
So, what you can do is you can handle tab click event and prevent this default behaviour using
e.preventDefault();
you have two options:
add ng-click="show($event)" for each tab
For example, in controller
$scope.show = function (e) {
e.preventDefault();
jQuery('.nav-pills[href="e.targrt.hash"]').tab('show')
};
Check Bootstrap document for more detail: http://getbootstrap.com/javascript/#tabs
or add directive to handle event.
<a show-tab href="#tab0" data-toggle="tab">Tools Home</a>
app.directive('showTab', function () {
// here first prevent deault behaviour of a tab, then add new click event which invokes jQuery related stuff for tabs
return function (scope, iElement, iAttributes) {
iElement.click(function (e) {
e.preventDefault();
$(iElement).tab('show');
});
};
This is the better option.
Please check this link how to do it: https://www.grobmeier.de/bootstrap-tabs-with-angular-js-25112012.html
Try this adding to your angjularjs
$(".yourTabClassName anchorTag").click(function(anyName) {
anyName.preventDefault();
});
Ex:
$(".nav a").click(function(e) {
e.preventDefault();
});
buddy, I think you are missing role='tab' attribute which does not invoke the angular router
I got it working by doing this. You'll notice that i'm using <app-tab-profile></app-tab-profile> in the Profile tab-pane. I'm not sure if this is best practice, but it seems to work. Routing is NOT setup for the TabProfileComponent.
<div class="section-container">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">...</div>
<div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab"><app-tab-profile></app-tab-profile></div>
<div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">...</div>
</div>
Hope this helps!
setTimeout(function() {
$('ul.tabs').tabs();
}, 100);

function is not called with anchor tag in angular

Unable to call logout function inside login controller. I have simple login and logout functionality using ui-router.
I am able to login and route to other page but I am not able to call logout function. I have tried all the possible solutions such as using:
<li><a href ng-click="$event.preventDefault();logout()">Logout</a></li> //only href
<li>Logout</li> //empty href
<li><a href ng-click="$event.preventDefault();logout()">Logout</a></li> //href with event
button class="btn" ng-click="logout()">Logout</button> //also button type
However, none of the above fired the logout function. I guess something wrong with scope or stateprovider.
Stateprovider:
myApp.config(function ($stateProvider, $urlRouterProvider) {
// default route
$urlRouterProvider.otherwise("/Home");
// ui router states
$stateProvider
.state('Home', {
url: "/Home",
views: {
content: {
templateUrl: 'views/HomePage.html',
controller: function ($scope) {
}
}
}
})
.state('LoggedIn', {
url: "/LoggedIn",
views: {
'content': {
templateUrl: 'views/LoggedIn.html',
controller: function ($scope) {
}
}
}
});
});
Login controller:
myApp.controller('loginController', ['$scope', '$http', 'jwtHelper', '$localStorage', '$sessionStorage', '$state', '$window', function ($scope, $http, jwtHelper, $localStorage, $sessionStorage, $state, $window)
{
$scope.loginForm = function (email, password) {
if (email !== undefined && password !== undefined) {
$http.post('rs/loginResource/login', {email: email, password: password})
.then(function (data) {
$localStorage.token = data.token;
$state.go('LoggedIn');
console.log(data.data.token);
})
.catch(function (error) {
console.log(error);
});
}
$scope.logout = function () {
alert("logout called"); //it is not firing the alert here
delete $localStorage.token;
$state.go('Home');
};
};
}]);
Index html:
<boyd>
<div id="wrap">
<div ui-view="content"></div>
</div>
</body>
Main html:
<div ng-controller="loginController">
<form class="form" method="post" ng-submit="loginForm(email, password)">
<div class="form-group">
<label class="sr-only">Email address</label>
<input type="email" ng-model="email" required>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" ng-model="password">
</div>
<div class="form-group">
<button type="submit">Sign in</button>
</div>
</form>
</div>
LoggedIn html:
<div ng-app="myApp">
<nav>
<div class="container">
<div ng-controller="loginController">
<ul>
<li><a href ng-click="logout()">Logout</a></li>
</ul>
</div>
</div>
</nav>
<h2>Logged In....</h2>
</div>
The logout function seems to be inside the loginForm function

Unable to change the name of login button using ng-show

I am setting a boolean value to true after user logs in and I want to update the login button status to logout. I tried using ng-show but apparently its not working.
States:
myApp.config(function ($stateProvider, $urlRouterProvider) {
// default route
$urlRouterProvider.otherwise("/Home");
var header = {
templateUrl: 'commonViews/Header.html',
controller: function ($scope) {
}
};
var footer = {
templateUrl: 'commonViews/Footer.html',
controller: function ($scope) {
}
};
// ui router states
$stateProvider
.state('Home', {
url: "/Home",
views: {
header: header,
content: {
templateUrl: 'views/HomePage.html',
controller: function ($scope) {
}
},
footer: footer
}
})
.state('LoggedIn', {
url: "/LoggedIn",
views: {
'header': header,
'content': {
templateUrl: 'views/LoggedIn.html',
controller: function ($scope) {
}
},
'footer': footer
}
});
});
UserService:
myApp.factory('UserService', function ($http, $localStorage, AuthenticationService) {
return {
logIn: function (email, password) {
return $http.post('rs/loginResource/login', {email: email, password: password})
.then(function (data) {
AuthenticationService.isLogged = true;
alert("Authentication loggedIn inside login controller: " + AuthenticationService.isLogged);
return data;
})
.catch(function (error) {
console.log(error);
});
},
logOut: function () {
if (AuthenticationService.isLogged) {
AuthenticationService.isLogged = false;
delete $localStorage.token;
}
}
};
});
myApp.factory('AuthenticationService', function () {
var auth = {
isLogged: false
};
return auth;
});
Login controller:
myApp.controller('loginController', ['$scope', '$http', 'jwtHelper', '$localStorage', '$sessionStorage', '$state', '$window', 'UserService', 'AuthenticationService', function ($scope, $http, jwtHelper, $localStorage, $sessionStorage, $state, $window, UserService, AuthenticationService)
{
$scope.token = "";
$scope.$storage = $localStorage;
$scope.loginForm = function (email, password) {
if (email !== undefined && password !== undefined) {
UserService.logIn(email, password).then(function (response) {
$localStorage.token = response.data.token;
if ($localStorage.token) {
$state.go('LoggedIn');
alert("scope loggedIn inside login controller: " + AuthenticationService.isLogged);
}
}).catch(function (status, data) {
console.log(status);
console.log(data);
});
}
$scope.logout = function logout() {
UserService.logOut().success(function () {
$state.go('/');
}).error(function (status, data) {
console.log(status);
console.log(data);
});
};
};
}]);
index.html:
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head></head>
<body>
<div ui-view="header"></div>
<div ui-view="content"></div>
<div ui-view="footer"></div>
</body>
</html>
Header html:
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<b>Logout</b>
<b>Login</b> <span class="caret"></span>
<ul id="login-dp" class="dropdown-menu">
<!---------------------------------Login Controller Here------------------------------------->
<li>
<div class="row">
<div class="col-md-12">
<form class="form" role="form" method="post" ng-controller="loginController" ng-submit="loginForm(email, password)" accept-charset="UTF-8" id="login-nav">
<div class="form-group">
<label class="sr-only" for="exampleInputEmail2">Email address</label>
<input type="email" class="form-control" ng-model="email" id="exampleInputEmail2" placeholder="Email address" required>
</div>
<div class="form-group">
<label class="sr-only" for="exampleInputPassword2">Password</label>
<input type="password" class="form-control" id="exampleInputPassword2" ng-model="password" placeholder="Password" required>
<div class="help-block text-right">Forget the password ?</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">Sign in</button>
</div>
</form>
</div>
</div>
</li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
After user is logged in, it changes the status to logout for split second and then back to login status again. I am not sure what's going wrong?
Add AuthenticationService to the scope of your controller,
$scope.AuthenticationService = AuthenticationService;
and remove $scope from your view/template
<ul class="nav navbar-nav navbar-right" ng-controller="loginController">
<li class="dropdown">
<b>Logout</b>
<b>Login</b> <span class="caret"></span>
</li>
Put an isLoggedIn() function in your header controller:
myApp.config(function ($stateProvider, $urlRouterProvider) {
// default route
$urlRouterProvider.otherwise("/Home");
var header = {
templateUrl: 'commonViews/Header.html',
controller: function ($scope, AuthenticationService) {
$scope.isLoggedIn = function() {
return AuthenticationService.isLogged;
});
}
};
var footer = {
templateUrl: 'commonViews/Footer.html',
controller: function ($scope) {
}
};
// ui router states
And in your header HTML use that function:
<a href="#" class="dropdown-toggle" data-toggle="dropdown"
ng-show="isLoggedIn()" ng-click="logout()"><b>Logout</b>
</a>
<a href="#" class="dropdown-toggle" data-toggle="dropdown"
ng-show="!isLoggedIn()">
<b>Login</b> <span class="caret"></span>
</a>
UPDATE
Your login controller's scope is a child of the header controller's scope. Your ng-show directives are not in your login controller's scope. By putting functions that query the AuthenticationService.isLogged state in the correct scope, the ng-show directives should work properly.
There are 2 issues in your code
AuthenticationService.isLogged
is not updated after successful login with UserService
You don't need to have $scope in your templates as any Angular expression that you pass in your HTML template will be resolved against the current scope.
I would suggest not to expose your services onto your view layer. Just add a property isLoggedIn on your scope which will determine whether to show Login or Logout buttons.
myApp.controller('loginController', ['$scope', '$http', 'jwtHelper', '$localStorage', '$sessionStorage', '$state', '$window', 'UserService', 'AuthenticationService', function ($scope, $http, jwtHelper, $localStorage, $sessionStorage, $state, $window, UserService, AuthenticationService)
{
$scope.token = "";
$scope.$storage = $localStorage;
// new property to hold login status
$scope.isLoggedIn = false;
$scope.loginForm = function (email, password) {
if (email !== undefined && password !== undefined) {
UserService.logIn(email, password).then(function (response) {
$localStorage.token = response.data.token;
if ($localStorage.token) {
// cache the login status for use in other controllers
AuthenticationService.isLogged = true;
// update the scope for use in templates
$scope.isLoggedIn = true;
$state.go('LoggedIn');
}
}).catch(function (status, data) {
console.log(status);
console.log(data);
});
}
$scope.logout = function logout() {
UserService.logOut().success(function () {
// cache the login status for use in other controllers
AuthenticationService.isLogged = false;
// update scope for use in templates
$scope.isLoggedIn = false;
$state.go('/');
}).error(function (status, data) {
console.log(status);
console.log(data);
});
};
};
}]);
With this, in your templates, you can just check for isLoggedIn like below
<ul class="nav navbar-nav navbar-right" ng-controller="loginController">
<li class="dropdown">
<a href="#" class="dropdown-toggle"
data-toggle="dropdown"
ng-show="isLoggedIn"
ng-click="logout()">
<b>Logout</b></a>
<a href="#" class="dropdown-toggle"
data-toggle="dropdown"
ng-show="!isLoggedIn">
<b>Login</b> <span class="caret"></span>
</a>
</li>
</ul>

$rootScope to set active tab not working

would anyone be able to help me on this issue I am having?
I have a NavCtrl for manage my active tag, I was able to change the active tab when click on the menu item, however when I click on the link in the body views, it take me to the page I want to, but the active tag is not change.
//controller for nevigation menu
sp.controller('NavCtrl', ['$scope', 'auth', '$window','$rootScope', function ($scope, auth, $window,$rootScope) {
$scope.LogOut = auth.logOut;
$scope.isLoggedIn = auth.isLoggedIn;
$scope.tab = $rootScope.navTav;
$scope.toTop = function(){
$window.scrollTo(0, 0);
};
}]);
I try to use the $rootScope to set the navTab, but it's still not working
//setting root scope
sp.run(function($rootScope) {
$rootScope.navTav = 1;
})
ui-Router
.state('qaanswer', {
url: '/qa/{quesId}',
views: {
view50': {
templateUrl: './qa/qaanswer.html',
controller: 'QAAnswerCtrl'
},
'view60': {
templateUrl: './shareviews/activityupdates.html',
controller: 'HomeCtrl'
}
},
onEnter:['$rootScope',function($rootScope){
$rootScope.navTav = 5;
}]
Thank you so much for the help
Update HTML :
<body ng-controller="NavCtrl">
<!-- Desktop Menu -->
<div>
<div>
<ul>
<a href="#/home" ng-class="{active: navTab === 1}" ng-click="navTab = 1">
<li>Home</li>
</a>
<a href="#/qa" ng-class="{active: navTab === 2}" ng-click="navTab = 2">
<li>QA</li>
</a>
</ul>
</div>
</div>
<div>
<div>
<div class="row">
<div ui-view="view50"></div>
<div ui-view="view60"></div>
</div>
</div>
</div>
</body>
Working plunker
You can simplify your implementation and have no issues. Simply use the $rootScope variable directly in your template along side ng-class like so:
<body ng-controller="NavCtrl">
<a ng-class="{red: $root.navTab===0}" ui-sref="first">first</a>
<a ng-class="{red: $root.navTab===1}" ui-sref="second">second</a>
<div ui-view></div>
</body>
Then update $rootScope in your controllers.
.controller('NavCtrl', function($scope, $rootScope) {});
.controller('FirstCtrl', function($scope, $rootScope) {
$rootScope.navTab = 0;
});
.controller('SecondCtrl', function($scope, $rootScope) {
$rootScope.navTab = 1;
});
Your states get to stay relatively simple:
.state('first', {
url: '/first',
templateUrl: 'first.html',
controller: 'FirstCtrl'
})
.state('second', {
url: '/second',
templateUrl: 'second.html',
controller: 'SecondCtrl'
})
plunker
Ideally you would make a directive for such a task, and avoid using $rootScope. A simple way to do this is to broadcast a message whenever you land on a new page, then listen on that event in your tab directive and flip the correct tab as active.

Categories