Node JS Request Response not working - node.js

This is my register route. If the registration is successful I want to redirect to the secret route. But the response is not working. When it is successful the page keeps loading and loading and doesn't redirect me to the secret route.
app.post('/register', function(req, res) {
User.create({
username: req.body.username,
password: req.body.password,
email: req.body.email
}, function(err, result, res) { **HERE**
if(err) throw err;
res.redirect('/secret');
console.log(result);
});
});
I tried this and the /secret route works but when I do this it doesn't check for registration errors and immediately redirects to the secret route.
app.post('/register', function(req, res) {
User.create({
username: req.body.username,
password: req.body.password,
email: req.body.email
}, function(err, result) { **HERE**
if(err) throw err;
console.log(result);
});
res.redirect('/secret');
});
I tried to add return err. So if there is an error the function will exit.
But here the /secret route still is still shown when I intentionally made an error in the registration. So the return is not exiting the function.
app.post('/register', function(req, res) {
User.create({
username: req.body.username,
password: req.body.password,
email: req.body.email
}, function(err, result) {
if(err) return err; **TRIED RETURN TO EXIT**
});
res.redirect('/secret');
});

That it keeps loading and loading indicates that the create user function returns an error in the callback. Or an error occured in the callback.
In case of an error no reponse might be send which will result in a dangling request.
In your code the reason is that you have to remove the res from the create user callback otherwise you will hide the original res of the middelware callback, which will result in an error. But you also have to handle the case when create user itself results in an error.
Your callback could look that way:
function(err, result) {
if(err) {
res.status(500).send('an error occured')
} else {
res.redirect('/secret');
console.log(result)
}
}
How exaclty the callback should look like depends on what you want to do in case of the error. You also might want to choose a different error code then 500 that would match better.

I believe you're confusing the callback-based nature of asynchronous programming in normal NodeJS with regular sequential programming.
The call to User.create will return immediately, and lines following it execute prior to anything within the callback you provide. So your res.redirect() call will trigger the immediate response of a redirect to the client. When the callback finally runs, the request has finished.
Instead, you will want to perform the redirection inside of the callback function, after checking for potential errors.
Your code should end up looking like this:
app.post('/register', function(req, res) {
User.create({
username: req.body.username,
password: req.body.password,
email: req.body.email
}, function(err, result) {
if(err) throw err;
// Since we got here, things went well presumably
res.redirect('/secret');
});
});

Related

User Registration using Mongo and NodeJs not working

i have made a usewr registration login in react and node . My signup route is working and user is saved in mongo , but signin route is not working ?
SignIn Component:-
signIn(){
axios.post('/tasks/signin', {
email: this.state.email,
password: this.state.password,
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
Routes are:-
Router.post('/signin', (req, res) => {
var User = new db1();
User.findOne({ email: req.body.email , password: req.body.password
}, function(err, user) {
console.log(user);
if(err) return next(err);
if(!user) return res.send('Not logged in!');
return res.send('Logged In!');
});
});
Error:
User.findOne is not a functionand i am getting 500 status.
Please help where am i wrong .
The findOne method is on the model, not the object. So it should be:
db1.findOne({ email: req.body.email , password: req.body.password
See previous question.
It seems to me that you require the model and assign it to a variable call db1 and create an instance called User. After that, you call the findOne method of the instance instead of the model itself.
If you are using Mongoose, this should be the problem. If not, please give some more details.
Also, it is usually a good practice to call your classes with PascalCase and your instances with camelCase. This way you won't get confused.

Node.js - Check if user exists

I'm using NodeJS and passport to let users create an account before they can see results of a quiz they've just taken. My challenge is I need to confirm the username is available before the page refreshes because the user will lose their results if this happens.
Again: I need to verify the username is not taken prior to refreshing.
I think I'm close but it is not working. How would I change my code to handle this challenge?
Currently if the user name is taken it returns an error on trying to create an account and the user ends up on the /failpage as shown below.
app.post('/quiz', usernameToLowerCase, emailToLowerCase, function(req, res) {
User.findOne({
username: req.body.username
}, function(err, user) {
if (err) {
alert(err)
if (user) {
alert('this username is already taken. Please choose another.')
console.log('there was a user');
return false;
}
}
});
var user = new User({
username: req.body.username,
email: req.body.email,
password: req.body.password,
})
user.save(function(err) {
console.log('this is the problem' + ' ' + err)
if (err) {
return res.redirect('/failpage')
}
req.logIn(user, function(err) {
if (err) {
console.log(err);
}
console.log('all looks good')
res.redirect('/results');
});
});
});
Solved it with this if anyone else is trying to do the same thing:
in app.js
app.get('/usercheck', function(req, res) {
User.findOne({username: req.query.username}, function(err, user){
if(err) {
console.log(err);
}
var message;
if(user) {
console.log(user)
message = "user exists";
console.log(message)
} else {
message= "user doesn't exist";
console.log(message)
}
res.json({message: message});
});
});
In js
$('#usercheck').on('change', function() {
$.get('/usercheck?username='+$('#usernameValue').val().toLowerCase(), function(response) {
$('#usernameResponseHidden').text(response.message)
if ($('#usernameResponseHidden').html() === "user exists"){
$('#usernameResponse').text('That username is taken. Please pick another')
}
To solve your problem I think you need to routes. At least a app.get('/quiz') which returns a boolean on if the user exists or not. The section User.findOne can be sent in that route instead. You just need to make a request using ajax when he looses focus of the username field of your form, and display a notification if the name is available or not.

Issues with req.flash within a post request

I check whether or not an email or username is taken. I then use then use flash to send a message to the client using req.flash('messages', 'That username is taken.'); The only problem is I can't call a request command within a function. I can send the message when I put it right after app.post('/signup', function(req, res) { How could I check if a username is taken and then send the req.flash command once it has been determined. I tried to create an if statement but because node is run asynchronously by the time the username is found and the variable is set to true, the if statement has been called. How could I use req.flash to send a message to the client within this post request.
app.post('/signup', function(req, res) {
var userDetails = User({
firstname: req.body.firstname,
username: req.body.username,
email: req.body.email,
password: bcrypt.hashSync(req.body.password1, bcrypt.genSaltSync(10))
});
User.findOne({
$or: [ { 'username': req.body.username}, {'email': req.body.email}]
}, function(err, user) {
if (user) {
if(user.username === req.body.username){
console.log('that username is taken');
req.flash('messages', 'that username is taken');
} else {
}
if(user.email === req.body.email){
console.log('that email is already in use');
req.flash('messages', 'that email is already in use');
} else {
}
} else {
userDetails.save(function(err) {
if (err) throw err;
});
console.log('change to login')
}
if (err) {
return done(err);
}
});
res.redirect('/');
});
It should be no problem to call req in a other function if req is defined in a higher level. I am not sure if your flash is session stored, if it not, the reasen why the messages is not flash is your redirection to route.
You redirect to root without waiting to the end of database request. I think you will only redirect if user is found? Include your redirect to the callback function.

How to get multiple parameters from API call in Node and Express

Need some help here as I am very lost in something that should be very simple. Either that or I am losing my mind.
Ok so I am routing my routes using the express.Router()
I will jump right to the problem:
This works:
apiRouter.get('/api/user/:id', secureAPIPages, function(req, res, next){
userModel.findOne({'profileID':req.params.id}, function(err, user) {
if(user){
res.json({
fullname: user.fullname,
about: user.about,
birthday: user.birthday,
email: user.email,
location: user.location
});
} else {
console.log('Result does not exist');
}
});
})
So when I make a call on a browser like:
http://localhost:3000/api/user/123456
It picks up the "id" variable and puts it in the req.params so all good there.
Now, the problem (this is what I want to make work, the above one is just to test out if my API routing worked):
apiRouter.get('/api/user', secureAPIPages, function(req, res, next){
userModel.findOne({'profileID':req.params.id}, function(err, user) {
if(user){
res.json({
fullname: user.fullname,
about: user.about,
birthday: user.birthday,
email: user.email,
location: user.location
});
} else {
console.log('Result does not exist');
}
});
})
Why is it not picking up my "id" and "name" variables when I run this URL on a browser:
http://localhost:3000/api/user?id=123456789&name=Shayan
As always, thanks for the help in advance.
Shayan
You should use query object as follows:
If this is the URL:
http://localhost:3000/api/user?id=123456789&name=Shayan
use
req.query.id, req.query.name

Redirects aren't working in ExpressJS

I'm trying to redirect on successful registration. I've knocked together this basic code to test out the principle:
app.post('/register', function(req, res, next) {
User.findOne({ username: req.body.username }, function (err, user) {
if (err) { return done(err); }
if (user) {
res.send(400);
} else {
var newUser = new User({ username: req.body.username, password: passwordHash.generate(req.body.password)});
newUser.save();
req.logIn(newUser, function(err) {
if (err) return next(err);
return res.redirect('/my-events');
})
}
});
});
However, when this triggers, my browser sees a 302, followed by a successful GET of the page that the /my-events endpoint serves up...but no redirect.
What's wrong? Using res.redirect works when the browser is loading an endpoint, it just doesn't seem to work as the result of a $.post.
You mentioned that you are using $.post for sending the data. If that is the case then server won't be able to redirect to the actual page. What you need to do is redirect the page manually yourself in the call back function of the post function like so.
$.post('your endpoint',function(){
window.location = 'page to redirect to';
});
This should do it.

Resources