Swapping Handlebars for Angular in MEAN app - javascript

I'm building a MEAN app with user authentication and I'm currently in the process of learning Angular (I like to learn by using whatever it is I'm learning in a practical way). Anyway, before I stripped the handlebars view engine and changed the view files from .hbs to .html I was able to display the username of the currently authenticated user like so:
Handlebars: {{user.username}} = req.user.username and it displays the username of the current authenticated user.
Rather than using render for rendering my pages, I'm now using sendfile:
app.get('/dashboard', Auth.ensureAuthenticated, function (req, res) {
res.sendfile('./app/views/admin.html', req);
});
I'd like to know how I go about rendering the username of the currently authenticated user in Angular.

You can send the user info by
Setting a global variable using your handlebar template.
app.get('/dashboard', Auth.ensureAuthenticated, function (req, res) {
res.render('admin',{user: user});
});
And in handlebar template add something like below
<script type="text/javascript">
window.user = {{user}};
</script>
wrap this global in angular service
angular.module('myApp').service('Global', ['$window', function($window){
function _getUser() {
return $window.user;
}
return {
user: _getUser()
};
}]);
Now in your controller, you can access the user data by injecting Global service
angular.module('myApp').controller('AdminController', ['$scope', 'Global', function($scope, Global) {
$scope.user = Global.user;
}])
User will be available in your angular partial views.
<div data-ng-controller="AdminController">
Welcome <span ng-bind="user"></span>
</div>
or you can send the information via cookie. After reading the cookie value inside _getUser function in angular service, delete the cookie.
or you can send an ajax request for fetching the data inside angular service.

Related

How to share data among the controllers using $broadcast, $on and $emit?

I am new to AngularJS web development.
STEP 1. During initialization, I get login information from a server with http call. Say, UserName, UserID and some other information.
STEP 2. After successful http call, I would like to populate the loginObj object such as
$scope.loginObj = { UserID = '', UserName = '', SomeData: '' };
$scope.loginObj.UserID = 1000;
$scope.loginObj.UserName = 'John Doe';
$scope.loginObj.SomeData = 'Some other data';
STEP 3. I would like to broadcast $scope.loginObj object information with
$rootScope.broadcast method.
All the examples I have seen used some kind of click button. No Button Click
solution.
STEP 4. In the child controller, I would like to receive the broadcasted
information from the Parent Controller.
How can I receive this information?
STEP 5. Some times I get some extra information at the Child Controller as well.
How can I receive this information from Child controller to the Parent
Controller?
Please provide me a solution or direct me some sites where I can get the example.
Instead of using broadcast, create an angularjs service in which you persist the login info you got from http call and you can inject this service in the controller in which you need login info.
create a service like this :
/*app is your angular module name*/
app.factory('authFactory',['$state',function( $state){
var authFactory = {
currentUser: {},
setCurrentUser: function(userinfo){
authFactory.currentUser = userinfo;
},
getCurrentUser: function(){
return authFactory.currentUser;
}
};
return authFactory;
}
in your login controller, inject authFactory, then once user is logged in, call authFactory.setCurrentUser and pass an object ({login: userlogin, email: useremail}). if you need the logged in user in another page, just inject authFactory in that page and call authFactory.getCurrentUser().

How to render data related specifically to a user when they login?

I'm working on a small application and I'm relatively new to programming. I've been using MEAN stack to start and have run into a snag. I have this code here that will render a name when a page is loaded.
<tr ng-repeat = "contact in users">
<td>{{contact.name}}</td>
</tr>
In my controller I have this code:
var myApp = angular.module('myApp', []);
myApp.controller('AppCtrl', ['$scope', '$http', function($scope, $http) {
console.log("Hello World from controller");
var refresh = function() {
$http.get('/users').success(function(response) {
console.log("I got the data I requested");
$scope.users = response;
$scope.contact = "";
});
};
refresh();
And then in my server I have this
app.get('/users', function (req, res) {
console.log('I received a GET request');
db.users.find( {_id: mongojs.ObjectId("55563359e430458542c0f36f")}, function (err, docs) {
console.log(docs);
res.json(docs);
});
});
This works great when I want to render that user. However this only allows me to render one of my users names. And it's whichever one I hard code into the db.user.find. What I would like to do is figure out a way to render a user's name based of off some specific session/variable when they login. So essentially when a user logs in have the values specific to their credentials display I used this tutorial https://scotch.io/tutorials/easy-node-authentication-setup-and-local for a beginners authentication. I figured I would be able to take the session and then somehow pass it down to my get statement on the server but so far I haven't been able to figure it out. Any suggestion would be great even if it means me scrapping what I have.

Angularjs: maintain http body after redirect

Hi everybody and sorry for the English (if you found some mistakes),
I have the next question: I am in the page A and I call a web service that returns a JSON in the body, after this I redirect to another page B.
My question: after the redirection, body is kept ? In oder words, can I get or access to the body (if the body contains the JSON)?
Example
The web service:
app.service('LoginService', ['$http', function($http) {
this.retrieveUser = function(username, password) {
var url = app.baseURI + username+"/"+password;
return $http.get(url);
};
...
JS redirect
self.login = function(username, password){
LoginService.retrieveUser(username, password)
.success(function (data) {
if(data.usuario.rol == "G")
window.location.href="http://localhost:8080/Natureadventure/html/gerente/gestionarActividades.html";
}).error(function(data){
$scope.loginForm.password.$setValidity("password", false);
});
};
Thanks!
Angular is completely client-sided, so, aside from setting something in localStorage, cookies or sessionStorage, no, you will not be able to do this.
The way around it is to turn your Angular application into a single-page application; you never really change the page of the website as such, but Angular can emulate the changing of your web page (i.e the content and the layout) through a library like ui-router or ngRoute.
The downside to this is that if you are either stuck with ugly hashbang URLs or you enable html5Mode, which breaks if you refresh the page. The way to fix that is to either a) stick with hashbang URLs or b) make your server redirect any unknown request to your index.html and let angular do the routing for you.

where to store global data in angular JS?

In angular Js i am trying to store user data such as profile name that should exist in most of routes is it a good practice to store them in the $rootScope. IF not where should i store them.
If you use a service it's everywhere available and if it should be persistent over page reloads and so on, then you can store the data in local storage or a cookie etc. and access it with your service on load.
angular.module('app')
.factory('UserService', ['SessionService', function(SessionService) {
SessionService.load();
var user = SessionService.getUser();
var service = {
setUser: function(u){ user = u; },
getUser: function(){ return user; }
};
return service;
}])
.controller('DemoCtrl', ['$scope', 'UserService', function($scope, UserService){
$scope.user = UserService.getUser();
}]);
I'm new to angular myself but the route I'm taking is to write a service. You could have a service that stores the user profile data. I would maybe put a method on the service to load the profile data and then store it locally in the service. You could then get this information via a getter method.

AngularJS - Broadcasting across controllers

Am trying a scenario where i Login, and, on success, want to store that LoginID and pass it to all other controllers for navigation/user management. Similar to a global variable set up, store once use everywhere concept.
Been using angularjs shared Services technique but its not picking the braodcaster LoginID in other controllers.
High level details:
1) Login HTML calls Login Controller from where i call back end server for user authentication
2) On success, broadcasted LoginID via shared service
3) from Login HTML, page navigates to OrderMenu Html and calls OrderMenu controller where am trying to fetch the User id which was broadcasted via the shared service.
4) but in the Order Menu controller the UserID shown is the initialized value i.e looks like app.factory is being called again and initializing the Broadcasted value.
I want to stop the reloading of app.factory. Looks like am missing something here.Any thoughts would be really helpful here.
Here is a quick implemention example of what you described.
And it seems to be working.
http://plnkr.co/edit/SPAB4W
My service is defined as follows:
app.factory('UserAuth', function() {
return {
userId: 'unknown',
authenticate: function( name ) {
// do server side authentication here...
this.userId = 'authenticatedUserId_Of_' + name;
}
};
});
In this example, when second controller (OrderCtrl) is getting called,
UserAuth.userId does not get re-initialized
and keeps the obtained userId of what authentication gives.
You may want to share your code.

Categories