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

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!

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.

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); });

Handling error sent back by express in postman

I am working with postman where i am sending my post data to api to insert data in mongodb.My issue is that i am not able to handle the error message properly. Here is my code for it
exports.addUser = (req, res, next) => {
const db = getdb();
// console.log(db)
// console.log(db)
db.collection12("user").insertOne({
name: req.body.name,
password:req.body.password
}).then((result) => {
res.send(result)
}).catch((err) => {
res.status(404).send('Error in adding')
});
};
so i knowingly made and error and wrote "collection12" so that i get and error but then in my catch method i am returning
("Error in addding")
so why then in postman i am not able to see this instead of that i am seeing a hude error meassge that says
See error here
I guess than same would be the issue in my react side where instead of getting my own error meassge i would get this huge message
You actually don't enter the catch block because it cannot even execute the db call. If you want a 404 error to be dispatched in this situation you need to add a try/catch statement like this:
exports.addUser = (req, res, next) => {
const db = getdb();
// console.log(db)
// console.log(db)
try {
db.collection12("user").insertOne({
name: req.body.name,
password:req.body.password
}).then((result) => {
res.send(result)
}).catch((err) => {
res.status(404).send('Error in adding')
});
} catch {
res.status(404).send('Error in adding')
}
};

js ':' Expected node js

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 })
// ...
});

ReactJS + MongoDB + NodeJS/ExpressJS: What is process.nextTick(function() { throw err; });?

In my ReactJS project, I am currently running the server with NodeJS and ExpressJS, and connecting to the MongoDB using MongoClient. I have a login API endpoint set up that accepts a request with user's username and password. And if a user is not found, should catch the error and respond with an error (status(500)) to the front-end.
But rather than responding to the front-end with an json error, the server gets crashed. I have tried everything to figure out why but still no luck.
How can I fix the following error? Any guidance or insight would be greatly appreciated, and will upvote and accept the answer.
I intentionally made a request with a username and a password ({ username: 'iopsert', password: 'vser'}) that does not exist in the database.
Here is the login endpoint:
//login endpoint
app.post('/api/login/', function(req, res) {
console.log('Req body in login ', req.body)
console.log('THIS IS WHAT WAS PASSED IN+++++', req._id)
db.collection('users').findOne({username: req.body.username}, function(err, user) {
console.log('User found ')
if(err) {
console.log('THIS IS ERROR RESPONSE')
// Would like to send this json as an error response to the front-end
res.status(500).send({
error: 'This is error response',
success: false,
})
}
if(user.password === req.body.password) {
console.log('Username and password are correct')
res.status(500).send({
username: req.body.username,
success: true,
user: user,
})
} else {
res.status(500).send({
error: 'Credentials are wrong',
success: false,
})
}
})
And here is the terminal error log:
Req body in login { username: 'iopsert', password: 'vset' }
THIS IS WHAT WAS PASSED IN+++++ undefined
User found
/Users/John/practice-project/node_modules/mongodb/lib/utils.js:98
process.nextTick(function() { throw err; });
^
TypeError: Cannot read property 'password' of null
at /Users/John/practice-project/server/server.js:58:12
at handleCallback (/Users/John/practice-project/node_modules/mongodb/lib/utils.js:96:12)
at /Users/John/practice-project/node_modules/mongodb/lib/collection.js:1395:5
at handleCallback (/Users/John/practice-project/node_modules/mongodb/lib/utils.js:96:12)
at /Users/John/practice-project/node_modules/mongodb/lib/cursor.js:675:5
at handleCallback (/Users/John/practice-project/node_modules/mongodb-core/lib/cursor.js:165:5)
at setCursorNotified (/Users/John/practice-project/node_modules/mongodb-core/lib/cursor.js:505:3)
at /Users/John/practice-project/node_modules/mongodb-core/lib/cursor.js:578:16
at queryCallback (/Users/John/practice-project/node_modules/mongodb-core/lib/cursor.js:226:18)
at /Users/John/practice-project/node_modules/mongodb-core/lib/connection/pool.js:430:18
And /Users/John/practice-project/node_modules/mongodb/lib/utils.js:98 is referring to the following:
var handleCallback = function(callback, err, value1, value2) {
try {
if(callback == null) return;
if(value2) return callback(err, value1, value2);
return callback(err, value1);
} catch(err) {
process.nextTick(function() { throw err; });
return false;
}
return true;
}
EDIT
Here are everything that's being imported to the server:
"use strict"
var express = require('express');
var path = require('path');
var config = require('../webpack.config.js');
var webpack = require('webpack');
var webpackDevMiddleware = require('webpack-dev-middleware');
var webpackHotMiddleware = require('webpack-hot-middleware');
var bodyParser = require('body-parser');
var MongoClient = require('mongodb').MongoClient;
var ObjectId = require('mongodb').ObjectID;
const jwt = require('jsonwebtoken')
var app = express();
var db;
var compiler = webpack(config);
app.use(webpackDevMiddleware(compiler, {noInfo: true, publicPath: config.output.publicPath}));
app.use(webpackHotMiddleware(compiler));
app.use(express.static('dist'));
app.use(bodyParser.json());
And this is how the request is made and error is caught:
loginUser(creds) {
var request = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(creds),
}
fetch(`http://localhost:3000/api/login`, request)
.then(res => res.json())
.then(user => {
console.log(user);
console.log('Successful')
})
.catch(err => {
console.log('Error is', err)
})
},
It looks to me like the error is being thrown on this line because user is not defined.
if(user.password === req.body.password) {...}
Take a harder look at your console statements.
1. Req body in login { username: 'iopsert', password: 'vset' }
2. THIS IS WHAT WAS PASSED IN+++++ undefined
3. User found
4. /Users/John/practice-project/node_modules/mongodb/lib/utils.js:98
5. process.nextTick(function() { throw err; });
^
6. TypeError: Cannot read property 'password' of null
7. at /Users/John/practice-project/server/server.js:58:12
Line 2 shows that req._id is undefined
Your User found statement is printed before you check if there is an error or if the user actually exists, so it isn't representative of there actually being a user.
Line 6 shows that the error is being thrown because you're trying to read a property of password from a null object.
I'd recommend modifying your login logic to look more like this:
//login endpoint
app.post('/api/login/', function(req, res) {
console.log('Performing login with req.body=');
console.log(JSON.stringify(req.body, null, 4));
// check for username
if (!req.body.username) {
return res.status(401).send({message: 'No username'});
}
// find user with username
db.collection('users').findOne({username: req.body.username}, function(err, user) {
// handle error
if(err) {
console.log('Error finding user.');
return res.status(500).send({message: 'Error finding user.'});
}
// check for user
if (!user) {
console.log('No user.');
return res.status(500).send({message: 'No user.'});
}
console.log('User found.');
// check password
if(user.password !== req.body.password) {
console.log('Wrong password.');
return res.status(401).send({message: 'Wrong password.'});
}
// return user info
return res.status(200).send(user);
});
Some final thoughts:
Make sure to handle the error (if it exists) and check that user exists before proceeding.
Always include return in your return res.status(...).send(...) statements, otherwise the subsequent code will execute.
It's generally not a good idea to save passwords as simple strings. Work toward encrypting them. Look at passport or bcrypt.
Hope this helps.

Categories