js ':' Expected node js - javascript

While trying to register user using nodejs and mongoose i get an error saying [js] ':' Expected on the dot notation at User.findOne(email: res.body.email).
I tried this
User: User.findOne(...)
but it raises the following error at runtime when sending a post request from postman
(node:13952) UnhandledPromiseRejectionWarning: ReferenceError: body is not defined
at User.User.findOne.then.user (C:\Users\Aman\Desktop\qwerty\routes\api\users.js:14:29)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:118:7)
(node:13952) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing ins
ide of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejectio
n id: 1)
this is my code
const User = require("../../Models/User");
router.post("/register", (req, res) => ({
User.findOne({ email: req.body.email }).then(user => {
if (user) {
show email registered before message
} else {
do something
});
const newUser = new User({
name: req.body.name,
email: req.body.email,
avatar: req.body.avatar,
password: req.body.password
});
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
newUser.password = hash;
newUser
.save()
});
});
}
})
}));

Remove the parentheses outside the body of the function (req, res) =>. It should look like this:
router.post("/register", (req, res) => {
User.findOne({ email: req.body.email })
// other code inside
});
() => ({}) will expect to return an object literal expression, e.g. JSON object. () => {} will execute the statements inside function body.
Read more at MDCN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Syntax

In an arrow function, the syntax you are using here
(req, res) => ({})
returns an object.
const foo = () => ({foo: 'bar'});
console.log(foo());
It's a shorthand for
const foo = () => {
return {
foo: 'bar'
}
};
console.log(foo());
So you either need to fix your code to really return a valid object, or remove ({ at the beginning, and the }) at the end of your function
router.post("/register", (req, res) => {
User.findOne({ email: req.body.email })
// ...
});

Related

TypeError: cb is not a function

So when I try to register using this code
router.post(
"/register",
catchAsync(async (req, res, next) => {
const { username, password, email, number, address } = req.body.user;
const user = new User({
email,
username,
number,
address,
isVerified: false,
});
const registredUser = await User.register(user, username, password);
req.login(registredUser, (err) => {
if (err) {
return next(err);
}
console.log(registredUser);
req.flash("success", "Dobro došli na About Women!");
res.redirect("users/confirm");
});
})
);
it flashes error in the title. I tried doing everything even referencing to my old code but none of it worked. This is log I get from console:
node_modules\passport-local-mongoose\index.js:247
promise.then((result) => cb(null, result)).catch((err) => cb(err));
^
TypeError: cb is not a function
How can I fix it? Also I am using passport for user registration.
That error message points to line 247 of index.js in the passport-local-mongoose package. See https://github.com/saintedlama/passport-local-mongoose/blob/main/index.js#L247
That is in the register function:
schema.statics.register = function (user, password, cb) {
The arguments are expected to be user, password, and callback. You are passing user, username, and password, so at line 247 it is trying to use the password as a callback function, which fails with the error message you noted.

res.send is not a function and error is not handled

I am getting this strange error from my function that creates users for my mongoose database. everything is correctly working, the user is being created. But res.send is not working so I dont get any thing back, instead I get an error
Here is the code
module.exports.newUser = (req, res) =>{
const newUser = new Users({
name: req.params.userName,
mail: req.body.mail,
password: req.body.password,
img: req.body.img,
})
newUser.save((err, res) => {
if (!err){
return res.send("successfully created user!");
}else{
return res.send(err.message);
}
});
};
here is the error:
node:events:368
throw er; // Unhandled 'error' event
^
TypeError: res.send is not a function
at C:\Users\tlege\OneDrive\Masaüstü\project 1\untitled_project\Server\src\controllers\userController.js:45:24
at C:\Users\tlege\OneDrive\Masaüstü\project 1\untitled_project\Server\node_modules\mongoose\lib\model.js:5097:18
at processTicksAndRejections (node:internal/process/task_queues:78:11)
Emitted 'error' event on Function instance at:
at C:\Users\tlege\OneDrive\Masaüstü\project 1\untitled_project\Server\node_modules\mongoose\lib\model.js:5099:15
at processTicksAndRejections (node:internal/process/task_queues:78:11)
What is the problem here, I really dont get it
you just have to change the code a bit,
Try this :
module.exports.newUser = (req, res) =>{
const newUser = new Users({
name: req.params.userName,
mail: req.body.mail,
password: req.body.password,
img: req.body.img,
})
newUser.save((err, result) => {
if (!err){
return res.send("successfully created user!");
}else{
return res.send(err.message);
}
});
};
Explaination :
You were overwriting the res received from the request by the res received from the save method.
I hope this answer helps you!

Why is res.json() returning null?

I'm trying to code the authentification part of my react app using jwt. I kept getting this error in my App.js file: 'Uncaught (in promise) TypeError: Cannot read properties of null (reading 'error')', which led me to find out that when a certain route is accessed, which should return some data about the user, the response body is actually empty. These are some snippets of my code, where I think the problem might be. Any help would be much appreciated, thanks in advance! Also, please let me know if I should provide other snippets of code
This is from my App.js file
const [authState, setAuthState] = useState({
username: "",
id: 0,
status: false,
});
useEffect(() => {
axios
.get("http://localhost:3001/users/auth", {
headers: {
accessToken: localStorage.getItem("accessToken"),
},
})
.then((response) => {
if (response.data.error) { //this is where the error appears
setAuthState({ ...authState, status: false });
} else {
setAuthState({
username: response.data.username, //if I comment the line where the error appears, I get the same error here and on the line below, but with 'username' and 'id' instead of 'error'
id: response.data.id,
status: true,
});
}
});
}, []);
This is where res.json doesn't return anything
router.get('/auth', validateToken, (req, res) => {
res.json(req.user);
});
This is the validateToken middleware
const { verify } = require('jsonwebtoken');
const validateToken = (req, res, next) => {
const accessToken = req.header("accessToken");
if (!accessToken) return res.json({ error: "User not logged in!" })
try {
const validToken = verify(accessToken, "importantsecret");
req.user = validToken; //we can access the username and id
if (validToken) {
return next();
}
} catch (err) {
return res.json({ error: err });
}
};
module.exports = { validateToken };
Okay, so in your middleware function, in this particular line,
const validToken = verify(accessToken, "importantsecret");
req.user = validToken; //we can access the username and id
if (validToken) {
return next();
}
Here, you are creating a constant variable named "validToken" and setting req.user to it. And then, you are checking if it exists, then run next(), but what if validToken is null/undefined? next() is never ran then!
Maybe it's because you literally don't return your response.
Try this one.
router.get('/auth', validateToken, (req, res) => { return res.json(req.user); });

passing variable to next middleware in req in express.js

I am trying to pass variable to the next middlewares through the req object.
getting some data from database and passing that data to request for next middlewares to use.
User.findone({ _id: someId })
.then(user => { req.user = user })
.catch(err => { })
After that then and catch block i am using next().
Therefore for the next middlewares i am getting req.user undefined.
but if i pass the next() function in the then block after
req.user = user like .then(user=> {req.user = user; next()}) than i am getting req.user a valid user object to use for the next middlewares.
what is the reason for this behaviour??
That's because the User.findOne function is asynchronous. The result of that function is only known in the then block.
const middleware = (req, res, next) => {
User.findOne({ _id: someId })
.then(user => {
req.user = user;
})
.catch(err => { });
next(); // If you put next() here, the request will go straight to the next middleware without waiting for User.findOne() to complete.
};
const middleware = (req, res, next) => {
User.findOne({ _id: someId })
.then(user => {
req.user = user;
next(); // Putting next() here is correct
})
.catch(err => {
next(err); // Remember to handle error to avoid hanging the request
});
};
then... is called after the User.findone promise resolves. Thus, if you put next() outside of then, it will be called before then.
You could read more details at promise-basics
Alternatively try to use async-await as it looks more straightforward.

Cannot add jwt token to node.js response

I'm new to javascript ecosystem and want to add jwt token to response out of this registration router:
router.post('/register', (req, res)=> {
User.findOne({email: req.body.email})
.then(user => {
if(user) {
return res.status(400).json({error: 'Email already exists'});
} else {
const newUser = new User({
username: req.body.username,
email: req.body.email,
password: req.body.password
});
bcrypt.genSalt(10, (err, salt)=> {
bcrypt.hash(newUser.password, salt, (err, hash)=> {
if (err) throw err;
newUser.password = hash;
newUser.save()
.then(user => res.status(200).json(user)) //<=Problem is here
.catch(err => console.log(err));
} )
})
}
})
});
The jwt snippet (which works fine on longin router) is this:
const payload = {
username: user.username
}
//sign token
jwt.sign(
payload,
keys.secretOrKey,
{ expiresIn: 3600},
(err, token)=> {
res.json({
success: true,
token: 'Bearer '+ token,
username: username
});
});
The problem is that I don't know how can I add the snippet to the response header.
When I add it after .then(user => I get a SyntaxError: Unexpected token const error.
How can I make it?
Sounds like you didn't wrap the jwt snippet within curly braces. Without them the arrow function where the problem appears only takes one expression. Paste the jwt snippet into the following snippet instead.
bcrypt.genSalt(10, (err, salt)=> {
bcrypt.hash(newUser.password, salt, (err, hash)=> {
if (err) throw err;
newUser.password = hash;
newUser.save()
.then(user => {
res.status(200).json(user);
<JWT_Snippet_here>
}
.catch(err => console.log(err));
})
})
Here you can see how the syntax of arrow functions is defined. The following quote shows the most important part.
(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
Curly braces are needed in order to be able to use a list of statements. The error you experienced occurred because your JavaScript engine expected a single expression but instead found a list of statements.

Categories