Nodejs get user by id - angularjs

Am using the MEAN stack for an app, i have users that i register and log in using satellizer everything work well.
But when i try to get user by it's id i get nothing, i can do request to get all users but not by id.
Note am using Ionicframework as a forntEnd framework.
Here is the code of my back end end point:
app.get('/api/me', function(req, res) {
User.findById(req.user, function(err, user) {
console.log(req.user);
console.log(user);
res.send(user);
});
})
my Front end code the controller:
.controller('ProfileCtrl', function($scope, $http, $stateParams, $ionicLoading, $timeout, $stateParams) {
$ionicLoading.show({
template: 'Loading...'
});
$http.get('http://localhost:3000/api/me')
.success(function(data) {
console.log("Recived data via HTTP", data);
$timeout(function() {
$ionicLoading.hide();
$scope.user = data;
}, 1000);
})
.error(function() {
console.log("Error while getting the data");
$ionicLoading.hide();
});
})
Request Header:
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,ar;q=0.6,fi;q=0.4,it;q=0.2,en-GB;q=0.2,en-CA;q=0.2
Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI1NTAxYjAxMmExMjRlZjIwMTc4M2ExMTQiLCJleHAiOjE0MjcxMzk0NDV9.x9QEdE4E-Vh1SklCheiZqsnJsg8jGzdJnPx2RXeZqS8
Connection:keep-alive
Host:localhost:3000
Origin:http://localhost:8100
Referer:http://localhost:8100/

you missed an important part in your server call, the "ensureAuthenticated":
app.get('/api/me', ensureAuthenticated, function(req, res) {
User.findById(req.user, function(err, user) {
res.send(user);
});
});
the ensureAuthenticate of this satellite example implemenation is a very simple version, it only puts the content of the token.sub into req.user. This is good enough for your query. Typically in a real app one would use passport middleware instead, load the user in the middleware and put it into req.user.
when using the mean stack typically req.user is set to the full user object, i.e. an instance of mongoose document. You want to search by id, so give the query an id:
try
User.findById(req.user._id, function(err, user) {
instead.
But, considering that req.user is already exactly the object that you are querying for, the whole query might just not be needed at all.
If you want to look up a different user than the authenticated one, you need to pass the id you want to query in the URL path, typically something like:
GET /api/users/{id}
then you can get this id using
req.params.id
and pass it to the findById() call

Related

show current user information from node to angular

I want to show current user information from nodejs to angular(view).
The problem is that i don't know how to pass and how to get User Id in node and angular .
Code :
Node
router.get('/:id/api/data.json', function(req, res, next) {
console.log(req.params.id);
var userId = req.params.id;
User.findById({_id:userId}, function (err, doc) {
if (err) throw err
if (doc){
res.json({
doc: doc,
userID:req.params.id
});
}
});
});
Angular :
app.controller('profileCtrl', function($scope, $http) {
$http.get("don't know how to get id from node").then(function (response) {
console.log(response.data);
});
});
Your Node.js router is listening to the url /:id/api/data.json. The :id part of that means Node.js is expecting a paramater there, which will get picked up by req.params.id in your Node.js file.
This means that you actually have to be passing in an id value as a part of the url. So your url would look something like /userid12345/api/data.json.
In your Angular file, that's the url you're going to be making the get request to. Which means you need to know the user's ID in your Angular file so you can get that specific url, e.g.:
var userId = 'userid12345';
$http.get('/' + userId + '/api/data.json').then(function(response) {
console.log(response);
});
Once you pass userId in as a part of the url, then Node can grab it using req.params.id and you can make your db call.

Mongoose query via Angular variable

I´m trying to query my mongoose model with an angular variable - an email adress.
I´ve got a variable from passport with contains the email <%= user.local.email %>.
The $http.getfor my Model looks like this:
app.get('/profile/project/:mail', function (req, res, next){
Project.findOne(req.params.mail, function (err, doc){
if(err) return next(err);
res.json(doc);
});
});
I can´t figure out how to pass the mail adress with the angular controller, to the GET request.
My try:
$http.get('/profile/project/' + <%= user.local.email %>).then(function (res){
$scope.project = res.data;
});
});
Setting the findOne parameter to a fixed mail adress worked, but I´ve got no idea how to pass the mail adress with the angular controller.
Hope you can help me.
Best regards, David
Update using passport
Getting near the solution, but now I only get the first data entry of my DB.
Sum it up, my route:
app.get('/profile/project/', function (req, res, next){
Project.findOne(req.user.local.email, function (err, doc){
if (err) return next(err);
if (!doc) return next(new Error('cant find'));
console.log(doc);
res.json(doc);
});
});
My angular controller:
<script>
var app = angular.module('myApp', []);
app.controller('projectCtrl', function($scope, $http) {
$http.get('/profile/project/').then(function (res){
$scope.project = res.data;
});
});
</script>
Passport works,I can log in and show the email address on the profile page. But with this route I´m just getting the first [0] entry from my database.
Are you sure you want angular to pass this variable?
If it's in passport, then it's likely the user's own email? If so then you should just look it up entirely on the backend.
If the email is really being passed from angular, then it doesn't make sense to have it in passport at all, and you would just pass it as a js var.
Edit
findOne should only return one result. Maybe you need to use find if you are trying to get multiple records.
Got the solution. Big thanks to #Austin_Greco!
Route:
app.get('/profile/project/', isLoggedIn, function (req, res, next){
Project.findOne({'author' : req.user.local.email}, function (err, doc){
if (err) return next(err);
if (!doc) return next(new Error('cant find'));
console.log(doc);
res.json(doc);
});
});
Angular Controller:
$http.get('/profile/project/').then(function (res){
$scope.project = res.data;
});

Mean.js angularjs querying the mongodb database

I know this is a stupid question, but I'm missing something and I'm lost.
I have created a new project using 'yo meanjs' thus creating the standard scaffolding.
From the public side of the application I am trying to search the Users for a user based not on their id but rather their email address.
Some how I need to write the query using Users.get or Users.query but I cannot find an example of how to do this. Do I have to create new controllers/routes on the app side?
On the public side I've tried many different things like:
var user = Users.query({
email: 'bob#this.com'
});
I can't seem to see the forest through the beautiful trees right now.
Thanks!
I guess the answer was a bit more complicated. This is working, although there may be a better way to do it.
I had to create a new function in one of the app user controllers:
exports.userByEmail = function(req, res, next, email) {
console.log('userByEmail ' + email);
User.findOne({
email: email
}).exec(function(err, user) {
if (err) return next(err);
if (!user) return next(new Error('Failed to load User with email ' + email));
res.json(user);
next();
});
};
Next, I had to create a new route:
app.route('/users/email/:emailAddr').get(users.me);
app.param('emailAddr', users.userByEmail);
Then I called it with a $htttp.get:
$http.get('/users/email/' + newEmail).
success(function(data, status, headers, config) {
// do something useful with data
}).
error(function(data, status, headers, config) {
$scope.error = 'Problem finding a user with that email';
});
The problem stemmed from my inability to use one of the existing CRUD calls to send a query json object.
You can use findOne().
User.findOne({email: req.body.email}, function(err, user){
//...
callback(err);
});

How can I return a database query and redirect at once?

I don't literally need to use "res.redirect()", I just mean I want to take the user to a different page using any workable method.
After the user enters their info, they click a button which calls createUser. createUser successfully adds a new entry to the database. I want the user to also be automatically redirected back to the index page ("/"). I have not found any way to do this. What I have below does hit "app.get('/'), but no redirect happens. Is it possible to put the redirect in app.post('/api/register-new-user')? Can I use window.location somehow within createUser? I have tried both of those ways to no avail.
// CLIENT =====
$scope.createUser = function() {
$http.post('/api/register-new-user', $scope.formData)
.success(function(data) {
$scope.formData = {}; // clear the form so our user is ready to enter another
$scope.users = data;
console.log(data);
// window.location = "./";
})
.error(function(data) {
console.log('Error: ' + data);
});
$http.get('/')
.success(function(data) {
})
.error(function(data) {
console.log('Error: ' + data);
});
};
//SERVER========
app.post('/api/register-new-user', function(req, res) {
bcrypt.genSalt(10, function(err, salt) {
if(err)
res.send(err);
bcrypt.hash(req.body.password, salt, function(err, hash){
if(err)
res.send(err);
User.create({
username : req.body.username,
password : hash
}, function(err, user) {
if(err)
res.send(err)
User.find(function(err, users) {
if(err)
res.send(err);
res.json(users);
});
});
});
});
});
app.get('/register', function(req, res) {
console.log('register');
res.sendfile('./public/views/register.html');
});
OK, so you are doing your browser/server interaction to create a user via AJAX and HTTP redirects over AJAX have no bearing on the URL/page loaded in the browser. So you can forget about server side HTTP redirects. Just send a 201 status to be nicely RESTful and call it good on the server.
On the client, if the POST succeeds you can just trigger a new route with $location.path('/');. Just make sure you declare $location so it gets injected by DI into your controller.
Also note that the active user probably needs to be set on the $rootScope if you want it to be broadly available to the rest of your controllers.
You could try
window.location.href()
Instead of window.location().
This should work with an absolute path.
Although as you are using Angular so it is possible to use the route provider to update the view with out redirecting the user.
Here is some documentation for the route provider.
https://docs.angularjs.org/tutorial/step_07

passportjs and passportlocal add users "Error: failed to serialize user into session"

I have followed the code here - > https://github.com/jaredhanson/passport-local/tree/master/examples/express3 for add local authentication for users.
The problem is when I try to add users,
So I created this route
app.get('/signup', function(req,res){
res.render('/signup');
});
app.post('/signup', function(req,res){
var body = req.body;
users.push(body);
res.redirect('/');
});
Then the page w the form It's
form(method='POST', action='/signup')
input(type='text', name='username', placeholder='username')
input(type='text', name='password', placeholder='password')
button.btn Register
The dummy DB It's the one on the example
users = [
{id:1, username: 'test', password:'papapa'}
];
So when I send the info w the form, all goes ok, but when I try to log in with the new created user, tells me "Error: failed to serialize user into session"
the serializeUser is this
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
findById(id, function (err, user) {
done(err, user);
});
});
The user being pushed in the POST /signup route will not have an ID, which the examples serialization code expects.
Change it to something like this, and it should work.
app.post('/signup', function(req,res){
var body = req.body;
body.id = users.length;
users.push(body);
res.redirect('/');
});
(Note that this is an example only, and not recommended for "real" apps.)
I guess you are missing the session serializer. Take a look to https://github.com/jaredhanson/passport, section 'Sessions'.
Basically, you need two functions, to save the current user into the session (passport.serializeUser) and to read it back (passport.deserializeUser).

Resources