AngularFire - Wait until user data is retrieved in controller - javascript

The user registers with username, email, and password. I authenticate using FirebaseSimpleLogin with the email, take the user id, and then load my user using the user id:
var ref = new Firebase(FIREBASE_URL + 'users'); // data containing user information
var users = $firebase(ref);
$rootScope.$on('$firebaseSimpleLogin:login', function (e, authUser) { // wait until authenticated
var query = $firebase(ref.startAt(authUser.uid).endAt(authUser.uid)); // find user by uid
query.$on('loaded', function () {
setCurrentUser(query.$getIndex()[0]); // get username from query
});
});
function setCurrentUser (username) {
$rootScope.currentUser = User.findByUsername(username);
}
Now, my problem is that I would like to redirect to the user profile page if I am logged in in my HomeCtrl:
app.controller('HomeCtrl', function ($rootScope, $scope, $location, Auth, User) {
// wait for current user to be set
// if signed in
// location.path('/user/' + currentUser.username);
});
Unfortunately, I am not sure how to wait until the setCurrentUser function is completed before I redirect. Is there a way I can have a function in my controller wait until this other function is completed?
I have a workaround, but I'm pretty sure this is not the right way to do it. Right now, I am watching for my user variable to be updated, and then calling all functions after it changes to a user, as in:
$scope.$watch(
function() { return $rootScope.currentUser }, // watch for variable to change
function() {
if ($rootScope.currentUser) { // if the current user is defined, change path
$location.path('/users/' + $rootScope.currentUser.username);
}
}
)

Try resolving the route for your users. Take the plunker demo below for example.
Plunker Demo
The app is just a simple login page to a profile page. It has a HomeCtrl that navigates to a ResolveCtrl (which is the profile page) after a login.
The HomeCtrl just manages a login view. When a user is successfully logged in we navigate to the profile page. (The Auth object is a custom wrapper I made available in the Plunker).
.controller('HomeCtrl', function($scope, Auth, $window) {
$scope.user = {
email: 'bob#email.com',
password: 'password'
};
$scope.login = function() {
Auth.login('password', $scope.user);
};
Auth.onLogin(function(e, user) {
console.log('logged in!');
$window.location.href = '#/resolve';
});
})
Now that we're logged in we'll go the ResolveCtrl. This controller resolves the current user before it has been loaded. That's the data parameter.
.controller('ResolveCtrl', function($scope, $route, data) {
$scope.user = data;
})
But where is that parameter coming from? We can set a resolve object in our $routeProvider. This tells the ResolveCtrl it can't load until we've resolved this promise. Since the Auth.getCurrentUser() returns a promise we just need to return that and it will get resolved for us.
.config(['$routeProvider',
function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: '_home.html',
controller: 'HomeCtrl',
})
.when('/resolve', {
templateUrl: '_resolve.html',
controller: 'ResolveCtrl',
resolve: {
data: function(Auth) {
// load the user before the view is loaded
return Auth.getCurrentUser();
}
}
})
.otherwise({
redirectTo: '/'
});
}
])
Now when the page gets loaded we know that the user will be there.

Related

how to check firebase auth before routeProvider send to page

I want a route to check and see if a Firebase user is signed in before it redirects someone to the /map.html page.
.when('/map', {
templateUrl: 'views/map.html',
controller: 'MapCtrl',
resolve: {
loggedIn: onlyLoggedIn()
}
});
I have tried using resolve (see code above) but I only get errors from the onlyLoggedIn() function that say "user is not defined". User is defined and if I try to pass in user to the function I get an error "Unknown provider: user"
var onlyLoggedIn = function ($location,$q,user) {
var deferred = $q.defer();
console.log("well: "+user);
if (user) {
console.log("user is signed in ");
deferred.resolve();
} else {
deferred.reject();
$location.url('/signup');
}
return deferred.promise;
};
How should I go about checking if a user is signed in with firebase before routing them to the /map page?
Firebase gives me the user variable and in 'other' places in my app it works, so the problem isn't user not being defined, but my onlyLoggedIn function not "getting" it(?)
Security rules in Firebase can prevent the page from data from being viewed without permission. You need a client-side solution to redirect the page. You do in routes.
This is complete code for the Angular Firebase
This is simple code demonstration. I hope that will work for you.
angular.module('myApp.routes', ['ngRoute', 'simpleLogin'])
.constant('ROUTES', {
'/home': {
templateUrl: 'partials/home.html',
controller: 'HomeCtrl',
resolve: {
// forces the page to wait for this promise to resolve before controller is loaded
// the controller can then inject `user` as a dependency. This could also be done
// in the controller, but this makes things cleaner (controller doesn't need to worry
// about auth status or timing of displaying its UI components)
user: ['simpleLogin', function(simpleLogin) {
return simpleLogin.getUser();
}]
}
},
'/chat': {
templateUrl: 'partials/chat.html',
controller: 'ChatCtrl'
},
'/login': {
templateUrl: 'partials/login.html',
controller: 'LoginCtrl'
},
'/account': {
templateUrl: 'partials/account.html',
controller: 'AccountCtrl',
// require user to be logged in to view this route
// the whenAuthenticated method below will resolve the current user
// before this controller loads and redirect if necessary
authRequired: true
}
})
/**
* Adds a special `whenAuthenticated` method onto $routeProvider. This special method,
* when called, invokes the requireUser() service (see simpleLogin.js).
*
* The promise either resolves to the authenticated user object and makes it available to
* dependency injection (see AuthCtrl), or rejects the promise if user is not logged in,
* forcing a redirect to the /login page
*/
.config(['$routeProvider', function($routeProvider) {
// credits for this idea: https://groups.google.com/forum/#!msg/angular/dPr9BpIZID0/MgWVluo_Tg8J
// unfortunately, a decorator cannot be use here because they are not applied until after
// the .config calls resolve, so they can't be used during route configuration, so we have
// to hack it directly onto the $routeProvider object
$routeProvider.whenAuthenticated = function(path, route) {
route.resolve = route.resolve || {};
route.resolve.user = ['requireUser', function(requireUser) {
return requireUser();
}];
$routeProvider.when(path, route);
}
}])
// configure views; the authRequired parameter is used for specifying pages
// which should only be available while logged in
.config(['$routeProvider', 'ROUTES', function($routeProvider, ROUTES) {
angular.forEach(ROUTES, function(route, path) {
if( route.authRequired ) {
// adds a {resolve: user: {...}} promise which is rejected if
// the user is not authenticated or fulfills with the user object
// on success (the user object is then available to dependency injection)
$routeProvider.whenAuthenticated(path, route);
}
else {
// all other routes are added normally
$routeProvider.when(path, route);
}
});
// routes which are not in our map are redirected to /home
$routeProvider.otherwise({redirectTo: '/home'});
}])
/**
* Apply some route security. Any route's resolve method can reject the promise with
* { authRequired: true } to force a redirect. This method enforces that and also watches
* for changes in auth status which might require us to navigate away from a path
* that we can no longer view.
*/
.run(['$rootScope', '$location', 'simpleLogin', 'ROUTES', 'loginRedirectPath',
function($rootScope, $location, simpleLogin, ROUTES, loginRedirectPath) {
// watch for login status changes and redirect if appropriate
simpleLogin.watch(check, $rootScope);
// some of our routes may reject resolve promises with the special {authRequired: true} error
// this redirects to the login page whenever that is encountered
$rootScope.$on("$routeChangeError", function(e, next, prev, err) {
if( angular.isObject(err) && err.authRequired ) {
$location.path(loginRedirectPath);
}
});
function check(user) {
if( !user && authRequired($location.path()) ) {
$location.path(loginRedirectPath);
}
}
function authRequired(path) {
return ROUTES.hasOwnProperty(path) && ROUTES[path].authRequired;
}
}
]);

need help understanding angular ui-router specifically passing mongodb data from state to state?

so I'm trying to pass my mongodb data from state to state using ui-router but having trouble making the links and controller as i'm making an app where users have a profile and are able to click on other people profile to see them. I'm able to get the entire list of users profiles but when click, it doesn't get the data so the user profile is blank.
app.js
angular.module('MyApp', ['ui.router']).config(function($stateProvider, $urlRouterProvider, $authProvider) {
/**
* App routes
*/
$stateProvider
.state('home', {
url: '/',
controller: 'HomeCtrl',
templateUrl: 'partials/home.html'
})
.state('about', {
url: '/about',
templateUrl: 'partials/about.html'
})
.state('match', {
url: '/match',
controller: 'matchCtrl',
templateUrl: 'partials/match.html'
})
.state('match.list', {
url: '/list',
controller: 'matchCtrl',
templateUrl: 'partials/match.list.html'
})
//this part is where I need help on most with the controller as it is not working
.state('match.profile', {
url: '/:displayName',
templateUrl: 'partials/match.profile.html',
controller: function($scope, $stateParams) {
$scope.user = $scope.getUserProfile[$stateParams.displayName];
}
});
$urlRouterProvider.otherwise('/');
account.js
angular.module('MyApp').factory('Account',function($http,$stateParams) {
return {
getProfile: function() {
return $http.get('/api/me/:id');
},
getAllProfile: function() {
return $http.get('/api/me');
},
getUserProfile: function() {
return $http.get('/api/me' + $stateParams.displayName);
},
updateProfile: function(profileData) {
return $http.put('/api/me/:id', profileData);
}
};
});
this part works where the mongodb data shows up on the list of users
match.list.html
<div ng-repeat="user in user">
<div class="col-xs-12 col-sm-6 col-md-6">
<div class="well well-sm">
<div class="row">
<h1>{{user.displayName}}</h1>
<h1>{{user.age}} </h1>
<a ng-href="#/match/{{user.displayName}}">
See {{user.displayName}}!
</a>
</div>
</div>
</div>
</div>
the profile part doesn't work as clicking on the a ng-href only lead to a blank profile without data.
match.profile.html
<h1>{{user.displayName}}</h1>
<h1>{{user.age}}</h1>
etc...
how would I go about fixing this so when i click on a user profile using ng-href on the list part. It go to the user profile with the data? Are there any examples that I find similar to this problem with ui-router?
edit
does it have something to do with my controller?
match.js
angular.module('MyApp')
.controller('matchCtrl', function($scope, toastr, Account) {
// set up the filter
$scope.sortUser = 'displayName';
$scope.sortReverse = false;
$scope.searchUser = '';
// get all of the users
$scope.getAllProfile = function () {
Account.getAllProfile()
.then(function (response) {
$scope.user = response.data;
})
.catch(function (response) {
toastr.error(response.data.message, response.status);
});
};
$scope.getUserProfile = function () {
Account.getUserProfile()
.then(function(response) {
$scope.user = response.data;
})
.catch(function (response) {
toastr.error(response.data.message, response.status);
});
};
// get the users
$scope.getAllProfile();
$scope.getUserProfile();
});
the rest api i'm using on node
app.get('/api/me/', function(req, res) {
User.find(function(err, user) {
res.send(user);
});
});
app.get('/api/me/:id', ensureAuthenticated, function(req, res) {
User.findById(req.user, function(err, user) {
res.send(user);
});
});
app.put('/api/me/:id', ensureAuthenticated, function(req, res) {
User.findById(req.user, function(err, user) {
if (!user) {
return res.status(400).send({ message: 'User not found' });
}
user.picture = req.body.picture || user.picture;
user.displayName = req.body.displayName || user.displayName;
user.email = req.body.email || user.email;
user.save(function(err) {
res.status(200).end();
});
});
});
Your match.profile controller is never resolving the promise that's returned from the API by getUserProfile, which is why the UI is blank.
First off, the controller needs the Account service injected into it, as others have noted. The getUserProfile method needs to be called correctly (use () instead of []).
controller: function($scope, $stateParams, Account) {
$scope.user = Account.getUserProfile($stateParams.displayName);
}
I'm also not sure that defining your Account factory to rely on $stateParams is going to work properly, since a factory is a singleton and $stateParams may not update properly as you change states; you'd have to check your Network tab in developer tools to ensure the API endpoint is being built correctly (or just log $stateParams inside the getUserProfile method). I think the better option though would be to take in the url variable as an argument. You're trying to pass it in anyway, but the method isn't expecting any arguments.
getUserProfile: function(displayName) {
return $http.get('/api/me' + displayName);
}
So finally, your controller should look like this
controller: function($scope, $stateParams, Account) {
Account.getUserProfile($stateParams.displayName)
.then(function (profile) {
$scope.user = profile;
});
}
A few other tips with UI-Router
With UI-Router, you should be concerned primarily with states of the application, not URLs. The correct way to transition between states in UI-Router then is to use ui-sref instead of ng-href. Note that ui-sref takes a state name, not a url, so instead of <a ng-href="#/match/{{user.displayName}}">, it'd be better to do <a ui-sref='match.profile({displayName: user.displayName})'> (note how you can still pass in your displayName variable to the $stateParams as an argument.
Your match.profile state is a perfect use case for a resolve function. Resolve functions allow you to load data before the state loads. This ensures that your data is always available to your state before the UI ever renders.
.state('match.profile', {
url: '/:displayName',
templateUrl: 'partials/match.profile.html',
resolve: {
profile: function ($stateParams, Account) {
return Account.getUserProfile($stateParams.displayName)
.then(function (profile) {
return profile;
});
}
},
controller: function($scope, profile) {
$scope.user = profile;
}
});
Notice how you can name the resolve function to be whatever you want, in this case profile. You can inject this directly into your controller and know for certain that your data will already be available to the UI as soon as the controller loads. No loading data, no resolving promises. This is much closer to the proper separation of concerns for a controller in the MVC architecture of Angular where a controller should not be concerned with loading its own data.
You aren't calling method correctly getUserProfile, It not available there in $scope, you have to call it from Account service. Method call happens by parenthesis () not like []. Next thing is, you can get data from getUserProfile method by putting .then function over it.
Code
.state('match.profile', {
url: '/:displayName',
templateUrl: 'partials/match.profile.html',
controller: function($scope, $stateParams, Account) {
Account.getUserProfile($stateParams.displayName)
.then(function(res){
var data = res.data;
$scope.user = data;
}, function(error){
console.log(error);
});
}
});
getUserProfile is a method in Account service. You have used
$scope.getUserProfile[$stateParams.displayName]
Change it to
Account.getUserProfile($stateParams.displayName);
It looks something like this
.state('match.profile', {
url: '/:displayName',
templateUrl: 'partials/match.profile.html',
controller: function($scope, $stateParams, Account) {
$scope.user = Account.getUserProfile[$stateParams.displayName];
}
});
and you have missed a slash in getUserProfile function:
getUserProfile: function() {
return $http.get('/api/me' + $stateParams.displayName);
},
which should be
getUserProfile: function(){
return $http.get('/api/me/' + $stateParams.displayName).then(function(res){
return res.data;
});
}

Resolve user data after full page reload in AngularJS

In my angular application, after full page reload happens, I want to be able to retrieve the user information via $http.get and if the user is logged in($http.get returns user info) then I want to show the 'about me' page, if user is not logged in then they should see the login page.
Currently I tried doing this in application.run method as shown in the code below, but since $http is async, the $rootScope.currentUser does not get set for some time and I get transferred to the login page by my $routeChangeStart event handler even when i'm logged in.
myAPp.config(function ($routeProvider) {
$routeProvider.when('/', {
templateUrl: '/app/homeView/home.html',
controller: 'HomeViewController'
}).when('/login', {
templateUrl: '/app/loginView/login.html',
controller: 'LoginController'
}).when('/me', {
templateUrl: '/app/userInfoView/userInfo.html',
controller: 'UserInfoController',
access: {
requiresLogin: true
}
}).otherwise({
redirectTo: '/'
});
}
);
myApp.run(function ($rootScope, $cookies, $location, UserService) {
UserService.getCurrentUser().then(
function (response) {
$rootScope.currentUser = response;
},
function () {
$rootScope.currentUser = null;
}
);
$rootScope.$on('$routeChangeStart', function (event, next) {
if (next.access !== undefined) {
if (next.access.requiresLogin && !$rootScope.currentUser) {
$location.path('/login');
} else {
$location.path('/me');
}
}
});
});
What is the correct way to solve this problem?
Following what #FuzzyTree started the following should do what you need
myApp.run(function($rootScope, $cookies, $location, UserService) {
var userPromise = UserService.getCurrentUser().then(
function(response) {
$rootScope.currentUser = response;
},
function() {
$rootScope.currentUser = null;
}
);
$rootScope.$on('$routeChangeStart', function(event, next) {
if (next.access !== undefined) {
if (next.access.requiresLogin && !$rootScope.currentUser) {
// prevent this change
event.preventDefault();
// let user promise determine which way to go
userPromise.then(function() {
// will call another `$routeChangeStart` but
// that one will pass around the above conditional
$location.path('/me');// modify using `next.url` if app gets more robust
}).catch(function() {
$location.path('/login');
});
}
}
});
});
you can:
check user then bootstrap angular application https://docs.angularjs.org/api/ng/function/angular.bootstrap
show state loading until user checking is over

AngularJS - disable some routes

As title already suggests, I'm trying to disable some routes. I'm using angular seed project, that already has a nice structure.
I'm using JWT and I'm trying to set up a structure where if a certain route requires user to be logged in, and the user is not logged in, it redirects him to the some other page.
On my angular.module I've added the following code:
.run(['$rootScope', 'userService', '$location', function($rootScope, userService, $location) {
userService.init();
$rootScope.$on('$routeChangeStart', function(event, next, current) {
$rootScope.isPrivate = next['authenticate'];
if ($rootScope.isPrivate) {
if (!userService.get())
$location.path('/');
}
});
}]);
And this is a protected route:
angular.module('myApp.view2', ['ngRoute', 'ngCookies'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/admin/vnos-stevilke', {
templateUrl: 'view2/view2.html',
controller: 'View2Ctrl',
authenticate: true
}).when('/admin/vnos-stevilke/:id', {
templateUrl: 'view2/view2.html',
controller: 'View2Ctrl',
authenticate: true
});
}])
.controller('View2Ctrl', ['$scope', 'webServices', '$location', '$routeParams', function($scope, webServices, $location, $routeParams) {
if ($routeParams.id)
webServices.getBranchById($routeParams.id, function(err, data) {
$scope.branch = data;
});
webServices.getCompanies(function(err, data) {
console.log(data);
console.log('no access!');
if (!err)
$scope.companies = data;
});
}]);
now at first it appears to be working OK: if I'm not logged in, the route is not displayed and I get redirected back to the root. But at a closer look I've noticed that console.log('no access!'); is still displayed in the console. So it appears that controller gets initialized.
It seems like the whole route is loaded and then gets redirected if user is not logged in. That is not the behaviour I'm looking for. I'm trying to HOLD the loading of the route until I'm sure the user is logged in.
Any ideas?
UPDATE:
I changed the code accordingly with the suggestion below, but it doesn't seem to work. Where have I gone wrong?
userService method that checks if user is logged in:
this.isLogged = function() {
var deferred = $q.defer();
if (current === null) return deferred.reject();
else return deferred.resolve(current);
};
Run method:
.run(['$rootScope', 'userService', '$location', function($rootScope, userService, $location) {
userService.init();
$rootScope.$on('$routeChangeError', function() {
$location.path('/');
});
}]);
Restricted page:
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/admin/vnos-stevilke', {
templateUrl: 'view2/view2.html',
controller: 'View2Ctrl',
resolve: function(userService) {
console.log('test');
return userService.isLogged();
}
});
}])
Here, the "test" never displays in console.
You need to just decide if you are letting user into restricted area with resolve route parameter.
If in one of resolve function resolves with a promise object that is rejected it stops entering requested route.
I would write something like:
$routeProvider.when('/restrictedURL',{
...some params,
resolve: function(userService){
return userService.get();
}
}
...and make userService.get return a Promise object that is resolved if session is active and rejected otherwise.
Now.. if promise is rejected a route won't be launched and $routeChangeError event is raised, so you need something like:
angular.module('yourapp').run(function($rootScope){
$rootScope.$on("$routeChangeError",function(){
$location.path('/');
});
});
read more about resolve parameter # https://docs.angularjs.org/api/ngRoute/provider/$routeProvider

AngularJS - show/hide nav items if user is logged in

I have a single-page AngularJS app, working with Express, node.js, and MongoDB via Mongoose. Using Passport for user management/authentication.
I'd like the navbar items to change based on whether a user is logged in or not. I'm having trouble figuring out how to implement it.
I find out if a user is logged in through an http request:
server.js
app.get('/checklogin',function(req,res){
if (req.user)
res.send(true);
else
res.send(false);
On the front end, I have a NavController calling this using Angular's $http service:
NavController.js
angular.module('NavCtrl',[]).controller('NavController',function($scope,$http) {
$scope.loggedIn = false;
$scope.isLoggedIn = function() {
$http.get('/checklogin')
.success(function(data) {
console.log(data);
if (data === true)
$scope.loggedIn = true;
else
$scope.loggedIn = false;
})
.error(function(data) {
console.log('error: ' + data);
});
};
};
In my nav, I am using ng-show and ng-hide to determine which selections should be visible. I am also triggering the isLoggedIn() function when the user clicks on the nav items, checking whether the user is logged in during each click.
index.html
<nav class="navbar navbar-inverse" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="/">Home</a>
</div>
<ul class="nav navbar-nav">
<li ng-hide="loggedIn" ng-click="isLoggedIn()">
Login
</li>
<li ng-hide="loggedIn" ng-click="isLoggedIn()">
Sign up
</li>
<li ng-show="loggedIn" ng-click="logOut(); isLoggedIn()">
Log out
</li>
</ul>
</nav>
Problem
There are other places in my app where the user can log in/out, outside of the scope of the NavController. For instance, there's a login button on the login page, which corresponds to the LoginController. I imagine there's a better way to implement this across my entire app.
How can I 'watch' whether req.user is true on the back end and have my nav items respond accordingly?
you can use $rootScope to share info across the entire app:
.controller('NavController',function($scope,$http, $rootScope) {
$scope.isLoggedIn = function() {
$http.get('/checklogin')
.success(function(data) {
console.log(data);
$rootScope.loggedIn = data;
})
.error(function(data) {
console.log('error: ' + data);
});
};
};
now you can change the value of loggedIn from other places in your app by accessing $rootScope.loggedIn in the same way it is done in the code above.
With that said, you should abstract the relevant code into a service and a directive. This would allow you to have one central place to handle, log in, log out, and the state of $rootScope.loggedIn. If you post the rest of the relevant code I could help you out with a more concrete answer
You can broadcast that event when user logs in successfully. And no need to keep polling your server if user is logged in you can keep a variable in memory that tells if you have a valid session or not. You can use a token-based authentication which is set in the server side:
services.factory('UserService', ['$resource',
function($resource){
// represents guest user - not logged
var user = {
firstName : 'guest',
lastName : 'user',
preferredCurrency : "USD",
shoppingCart : {
totalItems : 0,
total : 0
},
};
var resource = function() {
return $resource('/myapp/rest/user/:id',
{ id: "#id"}
)};
return {
getResource: function() {
return resource;
},
getCurrentUser: function() {
return user;
},
setCurrentUser: function(userObj) {
user = userObj;
},
loadUser: function(id) {
user = resource.get(id);
}
}
}]);
services.factory('AuthService', ['$resource', '$rootScope', '$http', '$location', 'AuthenticationService',
function ($resource, $rootScope, $http, $location, AuthenticationService) {
var authFactory = {
authData: undefined
};
authFactory.getAuthData = function () {
return this.authData;
};
authFactory.setAuthData = function (authData) {
this.authData = {
authId: authData.authId,
authToken: authData.authToken,
authPermission: authData.authPermission
};
// broadcast the event to all interested listeners
$rootScope.$broadcast('authChanged');
};
authFactory.isAuthenticated = function () {
return !angular.isUndefined(this.getAuthData());
};
authFactory.login = function (user, functionObj) {
return AuthenticationService.login(user, functionObj);
};
return authFactory;
}]);
services.factory('AuthenticationService', ['$resource',
function($resource){
return $resource('/myapp/rest/auth/',
{},
{
'login': { method: "POST" }
}
);
}]);
services.factory('authHttpRequestInterceptor', ['$injector',
function ($injector) {
var authHttpRequestInterceptor = {
request: function ($request) {
var authFactory = $injector.get('AuthService');
if (authFactory.isAuthenticated()) {
$request.headers['auth-id'] = authFactory.getAuthData().authId;
$request.headers['auth-token'] = authFactory.getAuthData().authToken;
}
return $request;
}
};
return authHttpRequestInterceptor;
}]);
controller:
controllers.controller('LoginCtrl', ['$scope', '$rootScope', 'AuthService', 'UserService',
function LoginCtrl($scope, $rootScope, AuthService, UserService) {
$scope.login = function () {
AuthService.login($scope.userInfo, function (data) {
AuthService.setAuthData(data);
// set user info on user service to reflect on all UI components
UserService.setCurrentUser(data.user);
$location.path('/home/');
});
};
$scope.isLoggedIn = function () {
return AuthService.isAuthenticated();
}
$scope.user = UserService.getCurrentUser();
}])
You can add user's session data inside the index.html using some templating library like EJS.
Just add ejs middleware:
var ejs = require('ejs');
// Register ejs as .html.
app.engine('.html', ejs.__express);
And then, when returning the index.html render the session data into the response.
res.render( "/index.html", {
session : {
user_data : JSON.stringify(req.user)
}
});
You'll now have access to this data in the index.html, now you need to load it into Angular app.
I used preload-resource example, but you can use your own way.
You can also use $localStorage if you want the login to persist outside of the current session. I've found this library has been super helpful for these types of situations. (https://github.com/grevory/angular-local-storage)

Categories