I need to show the name of current user in the top bar of my website. The user data should be disappeared when user logout. I used the following two services:
app.factory('Auth', ['$resource', function ($resource) {
return $resource('/user/login');
}])
.service('CurrentUser', [function () {
this.user= null;
}]);
Here is my login and topbar controllers.
app.controller('LoginCtrl', ['CurrentUser', 'Auth', '$location', function (CurrentUser, Auth, $location) {
this.login = function () {
var me = this;
me.user = Auth.save(me).$promise.then(
function (res) {
CurrentUser.user = res;
$location.path("/");
}, function (res) {
me.errors = res.data;
});
}
}])
.controller('TopBarCtrl', ['CurrentUser', function (CurrentUser) {
var me = this;
me.user = CurrentUser;
}])
Using this controllers and services in had to use {{contoller.user.user.name}} to show the user's name. Is there any way to use {{contoller.user.name}} instead and keep the two-way bindings?
You would have to use
me.user = CurrentUser.user;
As your are setting the result of your http.save in the first then to the .user property of CurrentUser.
What does the server result, e.g json, look like?
Related
I have AngularJS project.
in my login controller i've set user values in to localStorageService.set("user", res) when user loging success,it direct to profile html and controlling by Profile controller.in their i have $scope.user = localStorageService.get("user");
currently i can access this user only inside profile html.but i want to access this globally.
eg: in my header html.
how to set this to access in every ware in my project html pages?
Login controller
mymedApp.controller('LoginController', function ($scope, $rootScope, $location, $filter, $http, $window, $document, Common, localStorageService, SweetAlert, Facebook) {
$scope.user = {
user_id : "",
first_name : "",
last_name : "",
};
$scope.login = function () {
Common.get('mobile/signin', $scope.login, function (res, err) {
if (res.user_id > 0) {
localStorageService.set("user", res);
$rootScope.$emit('profileChanged', function () {
$window.location.href = '#/' + profile.js;
});
} else {
SweetAlert.error("Login request failed, please check the email and password and try again.", {
title : "Login Failed!",
confirmButtonColor : '#e74c3c'
});
}
}, true);
};
)};
Profile Controller
myApp.controller('ProfileController', function ($scope, $filter, $rootScope, $http, $window, $document, localStorageService,) {
var init = function () {
if (!localStorageService.get("user")) {
// $window.location.href = '#/login';
} else {
$scope.user = localStorageService.get("user");
}
};
init();
});
You can set,
var user = localStorageService.get("user");
and then set this user variable in a session like,
Session.setValue(variable name(username),user);
and then in which page you want to get that value you can get
Session.getValue(variable name which written during set session(username));
Since you are storing this in localstorage Service it is available globally. You can inject the localstorage service in your desired controller and get it by the same way.
if (!localStorageService.get("user")) {
// $window.location.href = '#/login';
} else {
$scope.user = localStorageService.get("user");
}
I want to find the ID of the logged in user and display it in a page. I am new to angular and I don't have much clue on how to handle a session..
I have an angular app which is connected to backend API (.net core).
I will show the instances where $rootScope is used in the website (login and authorization is already enabled). I need to get an understanding of this to learn the app.
In App.js :
//Run phase
myApp.run(function($rootScope, $state) {
$rootScope.$state = $state; //Get state info in view
//Should below code be using rootScope or localStorage.. Check which one is better and why.
if (window.sessionStorage["userInfo"]) {
$rootScope.userInfo = JSON.parse(window.sessionStorage["userInfo"]);
}
//Check session and redirect to specific page
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
if(toState && toState.data && toState.data.auth && !window.sessionStorage["userInfo"]){
event.preventDefault();
window.location.href = "#login";
}
if(!toState && !toState.data && !toState.data.auth && window.sessionStorage["userInfo"]){
event.preventDefault();
window.location.href = "#dashboard";
}
});
});
Users.js :
'use strict';
angular.module('users', []);
//Routers
myApp.config(function($stateProvider) {
//Login
$stateProvider.state('login', {
url: "/login",
templateUrl: 'partials/users/login.html',
controller: 'loginController'
});
//Factories
myApp.factory('userServices', ['$http', function($http) {
var factoryDefinitions = {
login: function (loginReq) {
$http.defaults.headers.common['Access-Control-Allow-Origin'] = '*';
return $http.post('http://localhost:1783/api/token?UserName='+loginReq.username+'&password='+loginReq.password).success(function (data) { return data; });
}
}
return factoryDefinitions;
}
]);
//Controllers
myApp.controller('loginController', ['$scope', 'userServices', '$location', '$rootScope', function($scope, userServices, $location, $rootScope) {
$scope.doLogin = function() {
if ($scope.loginForm.$valid) {
userServices.login($scope.login).then(function(result){
$scope.data = result;
if (!result.error) {
window.sessionStorage["userInfo"] = JSON.stringify(result.data);
$rootScope.userInfo = JSON.parse(window.sessionStorage["userInfo"]);
//$localStorage.currentUser = { username: login.username, token: result.data };
//$http.defaults.headers.common.Authorization = 'Token ' + response.token;
$location.path("/dashboard");
}
});
}
};
}]);
I came to know that the information about the user will be available in $rootScope.userInfo. If so, how can I take a value inside it?
Please explain with an example if possible. Thanks in advance.
One:
myApp.controller('loginController', [
'$scope', 'userServices', '$location',
'$rootScope',
function($scope, userServices, $location, $rootScope) {
Inside the controller, $rootScope was injected which makes you have access to the userInfo in that controller.
so if you inject $rootScope into another controller and console.log($rootScope.userInfo) you would see the users data.
myApp.controller('anotherController', ['$scope', '$rootScope', function
($scope, $rootScope){
console.log($rootScope.userInfo) //you'd see the users data from sessionStorage
});
According to this post on quora
$scope is an object that is accessible from current component
e.g Controller, Service only. $rootScope refers to an object
which is accessible from everywhere of the application.
You can think $rootScope as global variable and $scope as local variables.
$rootScope Defn.
In your case, once the user is logged in a key "userInfo" in sessionStorage is created and the same data is copied to $rootScope.userInfo. To check the fields in the userInfo after login try
console.log($rootScope.userInfo);
and print it in the console or open your session storage in your browser debugger tools [for chrome open developer tools>applications>sessionstorage>domainname] to view the values in the "userInfo" key.
Suppose you have
{
uid: "10",
fullname: "John Doe"
}
you can access uid in the script using $rootScope.userInfo.uid or $rootScope.userInfo['uid'].
Just in case you are unable to read the code, here is an explanation
if (window.sessionStorage["userInfo"]) {
$rootScope.userInfo = JSON.parse(window.sessionStorage["userInfo"]);
}
is checking the user is logged in or not.
the factory
myApp.factory('userServices', ['$http', function($http) {
var factoryDefinitions = {
login: function (loginReq) {
$http.defaults.headers.common['Access-Control-Allow-Origin'] = '*';
return $http.post('http://localhost:1783/api/token?UserName='+loginReq.username+'&password='+loginReq.password).success(function (data) { return data; });
}
}
is calling the server to get the userInfo object.
$scope.doLogin = function() {
if ($scope.loginForm.$valid) {
userServices.login($scope.login).then(function(result){
$scope.data = result;
if (!result.error) {
window.sessionStorage["userInfo"] = JSON.stringify(result.data);
$rootScope.userInfo = JSON.parse(window.sessionStorage["userInfo"]);
//$localStorage.currentUser = { username: login.username, token: result.data };
//$http.defaults.headers.common.Authorization = 'Token ' + response.token;
$location.path("/dashboard");
}
});
}
};
$scope.doLogin is calling the above factory and storing the userInfo object.
I have a angular service function that is being called multiple times.
In the index.html page I have the following line:
<li><i class="pull-right"></i><br/>{{appCtrl.service.getCurrentUser()}} </li>
In the application controller I set the variable
appCtrl.controller('AppController', function ($state, securityService, $log) {
$log.info('App controller');
var appCtrl = this;
appCtrl.service = securityService;
});
In my service I exposed the function
login.factory('securityService', function ($window, $log) {
var currentUser;
return {
setCurrentUser: function (user) {
currentUser = user;
$window.sessionStorage.setItem('User', JSON.stringify(currentUser));
},
getCurrentUser: function () {
$log.info('Calling current user');
if (!currentUser) {
var storedObject = $window.sessionStorage.getItem('User');
currentUser = JSON.parse(storedObject);
}
return currentUser;
}
}
});
The following line in the getCurrentUser function gets called multiple times when the application starts up or page refresh is being done.
$log.info('Calling current user');
The controller is being called only once, I monitor it by looking at $log.info('App controller');
Is it being called as part of the dirty checking process or am I doing something wrong?
Angular calls your function on every digest cycle, you can set breakpoint inside the function and check it. If you are on 1.3 version, then please take a look at One Time Binding feature. If not then call the service inside the controller and bind view to some scope variable:
$scope.currentUser = securityService.getCurrentUser();
And inside view bind to scope variable:
{{currentUser}}
Try this, this is correct factory declaration. Because internally AngularJS calls yout factory like: securityService(injects); , each time you inject (use) your factory.
login.factory('securityService', function ($window, $log) {
var currentUser;
return {
setCurrentUser: function (user) {
currentUser = user;
$window.sessionStorage.setItem('User', JSON.stringify(currentUser));
},
getCurrentUser: function () {
$log.info('Calling current user');
if (!currentUser) {
var storedObject = $window.sessionStorage.getItem('User');
currentUser = JSON.parse(storedObject);
}
return currentUser;
}
};
});
Basically I have this controller:
angular.controller('AddUsersCtrl', function ($scope, UsersService) {
$scope.users = [];
function toggleUser (user) {
user._toggled = !user._toggled;
}
function addAll ()
var users = $scope.users;
UsersService
.addMany(users)
.success(function (response) {
// ...
})
}
});
It is the controller of a page where users can add multiple users at once, and each users can be toggled (basically it the toggled is the UI state which is used by the view to toggle user information)
But as you can see, the addAll function refers to the users on the scope and then calls a "addMany" method from UsersService. At this point somehow the _toggled variable should be filtered out because else it will also send "_toggled" to the backend.
Now a simple solution would be to loop through the users and remove the "_toggled" variable, but is there a better way or is my structure wrong?
You could use a separate array for your attribute, like this:
angular.controller('AddUsersCtrl', function ($scope, UsersService) {
$scope.users = [];
$scope.toggledUsers = {};
function toggleUser (user) {
$scope.toggledUsers[user] = !$scope.toggledUsers[user];
}
function addAll ()
var users = $scope.users;
UsersService
.addMany(users)
.success(function (response) {
// ...
})
}
});
I'm using angularFireAuth and I want to retrieve the logged in user's info and use in
all the controllers or services when the app is initial.
Currently, I used this in every controller but i having some problem.
$scope.$on("angularFireAuth:login", function(evt, user){
console.log(user);
});
The callback will not call if it is not a full page load or return null when app initial.
I need some tips for how can I return the authenticated user's info so I can use when app is initial and in all the controllers and services.
Example
When in controller or services
$scope.auth.user.id will return user's ID
$scope.auth.user.name will return user's name
etc
I would start with a userService for this:
angular.module('EventBaseApp').service('userService', function userService() {
return {
isLogged: false,
username: null
}
});
And write a LoginCtrl controller:
angular.module('EventBaseApp')
.controller('LoginCtrl', function ($scope, userService, angularFireAuth) {
var url = "https://example.firebaseio.com";
angularFireAuth.initialize(url, {scope: $scope, name: "user"});
$scope.login = function() {
angularFireAuth.login("github");
};
$scope.logout = function() {
angularFireAuth.logout();
};
$scope.$on("angularFireAuth:login", function(evt, user) {
userService.username = $scope.user;
userService.isLogged = true;
});
$scope.$on("angularFireAuth:logout", function(evt) {
userService.isLogged = false;
userService.username = null;
});
});
Inject the userService anywhere you want the user.
My app that am currently working on that uses this - https://github.com/manojlds/EventBase/blob/master/app/scripts/controllers/login.js
Based on ideas presented here - http://blog.brunoscopelliti.com/deal-with-users-authentication-in-an-angularjs-web-app
i'm not sure quite what your question is. but if you are looking to authorise once rather than in each controller, you can put the code into the module instead and put it into the $rootScope.
var myapp = angular.module('myapp').run(
function ($rootScope) {
$rootScope.user = null;
$rootScope.$on("angularFireAuth:login", function (evt, user) {
$rootScope.user = user;
});
});