Node server method not firing - node.js

I have the following web service that we have created.
router.post('/register', (req, res) => {
const user = req.body;
// registerSchema.validate(user, registerSchema, (err, result) => {
// if (err)
// res.status(500).end(err.message);
// });
findUserByEmail(user.email, (err, userFeedback) => {
console.log('Fired.');
if (userFeedback)
res.status(500).end(JSON.stringify("User already exists"));
});
const passwordPromise = util.promisify(bcrypt.hashSync);
const pass = bcrypt.hashSync(user.password);
createUser(user.name, user.email, pass, [], (err) => {
if (err)
res.status(418).end(JSON.stringify("Failed to create user."));
});
res.status(200).end(JSON.stringify("Signup successful."));
});
We are using this to register a user. Here are the methods we are calling in this part of the web service.
function createUser (userName, userEmail, userPass, dev, cb) {
var mg = require('mongodb').MongoClient;
mg.connect(url, { useNewUrlParser: true, useUnifiedTopology: true }, function(err, db){
var dbo = db.db(myDB);
var user = { name: userName,
email: userEmail,
password: userPass,
devices: dev };
var insert = util.promisify(dbo.collection("Users").insertOne);
dbo.collection("Users").insertOne(user, function(err, res) {
if (err) throw err;
console.log(`${user.name} has been added.`);
db.close();
sendEmail(userEmail,
'The CRUST Company welcomes you!',
'Thank you for signing up for our services!' );
});
});
}
//See if a user exists
function findUserByEmail (userEmail) {
var mg = require('mongodb').MongoClient;
mg.connect(url, { useNewUrlParser: true, useUnifiedTopology: true },
function(err, db){
var dbo = db.db(myDB);
var query = { email : userEmail };
var find = util.promisify(dbo.collection("Users").find);
return dbo.collection("Users").find(query).toArray(function(err, result) {
if (err) throw err;
db.close();
});
});
}
The createUser seems to be working fine but the FindUserByEmail is not firing at all. We even tried console.log within the method and got no response. Any ideas on why this method may not be firing? Thx

Your calling code passes findUserByEmail() a callback function:
findUserByEmail(user.email, (err, userFeedback) => {
console.log('Fired.');
if (userFeedback)
res.status(500).end(JSON.stringify("User already exists"));
});
But, your actual implementation of that function doesn't accept a callback and thus never calls it so of course the callback you pass never gets called.
Also, there are multiple asynchronous design problems. You are treating asynchronous operations like they are blocking. They are not. You must continue the flow of your code INSIDE the callback function, not after the function call which you do correctly inside of findUserByEmail() but do not do correctly in your request handler where you call it.
Also, createUser() declares a callback as an argument, but never calls it so the callback you pass to createUser() will also never get called.

Related

Why my function for retrieving data from mongodb is returning undefined?

I am trying to return all the entries from a mongodb collection from a nodejs.
I had written the function and it works if i console log the result i see all the objects from the colletion, but if i try to return the result i am getting undefined.
I cant figure it out why? I had also tried to JSON stringify and JSON parse after but still no success.
Here is my code:
`
const mongoUrl = "mongodb://192.168.8.156:27017/";
const getRoomReadings = function (id) {
MongoClient.connect(mongoUrl, function (err, db) {
if (err) throw err;
let dbo = db.db(`room${id}`);
dbo
.collection("env")
.find({})
.toArray(function (err, result) {
if (err) throw err;
return result;
});
});
};
// API RoomX route
app.get("/api/r:id", (req, res) => {
const rez = getRoomReadings(req.params.id);
console.log(rez);
});
`
I am using nodejs with express.
Please help me. Thanks in advance.
I had also tried to JSON stringify and JSON parse after but still no success.
I don't know why you created the connection each time you do the request but using promises will help you.
Example:
const mongoUrl = "mongodb://192.168.8.156:27017/";
const getRoomReadings = function (id) {
return new Promise((res, rej) => {
MongoClient.connect(mongoUrl, function (err, db) {
if (err) rej(err);
let dbo = db.db(`room${id}`);
dbo
.collection("env")
.find({})
.toArray(function (err, result) {
if (err) rej(err);
return res(result);
});
});
})
};
// API RoomX route
app.get("/api/r:id", async (req, res) => {
const rez = await getRoomReadings(req.params.id);
console.log(rez);
});
a better way to create a connection it creating a file call conn.js and inside that file create your connection
const { MongoClient } = require("mongodb");
const connectionString = process.env.ATLAS_URI;
const client = new MongoClient(connectionString, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
let dbConnection;
module.exports = {
connectToServer: function (callback) {
client.connect(function (err, db) {
if (err || !db) {
return callback(err);
}
dbConnection = db.db(<db_name>);
console.log("Successfully connected to MongoDB.");
return callback();
});
},
getDb: function () {
return dbConnection;
},
};
initialize the connection and use getDb to get the connection

Using node.js 'util' to promisify is returning an error

I'm trying to create a function in a file to return a promis, which I will call form another file. I'm trying to use the 'util.promisify' to wrap the function, but I'm getting an error. Here is the code and the error:
from my 'checkEmail.js':
const Profile = require('../../models/profile');
const util = require('util');
var exports = module.exports = {};
exports.findEmail = util.promisify(checkEmail());
function checkEmail (email) {
Profile.findOne({ 'emails': { $elemMatch: { email_address: email } } }, (err, userEmail) => {
let conclusion = false;
if (err) {
console.log('Error in looking up an existing email');
} else {
if (userEmail) {
console.log('We found an existing owner for email: ' + email);
conclusion = true;
}
}
return conclusion;
})
}
Calling it on 'profile.js':
router.route('/addemail/:id')
// ADD EMAILS
.put(function (req, res) {
Profile.findOne({ 'owner_id': req.params.id }, function (err, profile) {
if (err)
res.send(err);
EmailCheck.findEmail(req.body.email_address).then((data)=>{
console.log('The answer is: ', data);
});
profile.emails.push({
email_type: req.body.email_type,
email_address: req.body.email_address
})
profile.save(function (err) {
if (err)
res.send(err);
res.json(profile);
});
});
});
The error I'm getting is:
Config for: http://localhost:3000
internal/util.js:272
throw new ERR_INVALID_ARG_TYPE('original', 'Function', original);
Any help would be appreciated.
In order to promisify the function that you pass to util.promisify must:
Take a function following the common error-first callback style, i.e.
taking a (err, value) => callback as the last argument, and returns a version that returns promise
So you can either promisify Profile.findOne, or pass a callback as the last argument to checkEmail
function checkEmail (email, callback) {
Profile.findOne({ 'emails': { $elemMatch: { email_address: email } } }, (err, userEmail) => {
let conclusion = false;
if (err)
return callback(new Error('Error in looking up an existing email'));
if (userEmail) {
console.log('We found an existing owner for email: ' + email);
conclusion = true;
}
return callback(null, conclusion);
})
}
And then you should call it like this:
exports.findEmail = util.promisify(checkEmail);
Otherwise you're passing to .promisify the returned value of checkEmail which is not a function following the style commented above.
You have typo, use util.promisify(checkEmail) instead, parentheses are redundant

Data and salt arguments required

I'm trying to hash the password of admin in my site. I have searched and found out that this error is because of being null or undefined the value that we want to hash it.
here is my code, whenever I console.log(admin) it returns {}, I don't know why.
adminSchema.pre('save', (next) => {
var admin = this;
console.log(admin)
bcrypt.hash(admin.password, 10, (err, hash) => {
if (err) return next(err);
admin.password = hash;
next();
});
});
var adminModel = mongoose.model('Admin', adminSchema);
module.exports = adminModel;
server side code:
var adminModel = require('./../models/admins');
router.post('/register', (req, res) => {
var newAdmin = {
adminName: req.body.adminName,
faculty: req.body.faculty,
email: req.body.email,
password: req.body.password
}
adminModel.create(newAdmin, (err, admin) => {
if (err) {
console.log('[Admin Registration]: ' + err);
}
else {
console.log('[Admin Registration]: Done');
req.session.adminId = admin._id;
res.redirect('/admin/submitScore')
}
})
});
Unfortunately, I can't find the reason of that the console.log(admin) is empty. I would be thankful if anyone could help me.
The keyword this changes scope when used in arrow functions. See more here. This is not a problem in your express route, but in your mongoose middleware it is. Change your function to not use this or make an old fashioned function(){}

The findOrCreate method has not been setup

I have created the custom user with base User and i am searching the following email exist in db or not , if email exist then don't create it and log the access token .
module.exports = function (User) {
let app = require('../../server/server');
var loopback = require('loopback');
var credentials = { email: 'foo#foo.com', password: 'password' };
var filter = {
'where': {
'email': credentials.email
}
};
loopback.User.findOrCreate(filter, credentials, function (err) {
if (err) throw err;
User.login(credentials, function (err, token) {
if (err) throw err;
console.log(token);
process.exit();
});
});
Error:
Error: Cannot call User.findOrCreate(). The findOrCreate method has not been setup. The PersistedModel has not been correctly attached to a DataSource!
Try checking your Datasource configuration and see if it's properly connected to the Database.
Just try by
User.findOrCreate(filter, credentials, function (err) { });
As in Loopback doc
PersistedModel.findOrCreate([filter], data, callback)
Reference Link : https://apidocs.strongloop.com/loopback/#persistedmodel-findorcreate

NodeJs - calling one method from another in server controller

With the following controller, how can I call one method from another in the same controller?
Specifically, calling login() within a successful signup(), while retaining the same functionality for login() when it is used by a form?
The line this.login(newUser) does not work, nor does plain old login(newUser)
In both scenarios, I get the error:
TypeError: Cannot call method 'login' of undefined
var mongoskin = require('mongoskin');
module.exports = {
login: (function (req, res) {
req.db.collection('auth').findOne({_id: mongoskin.helper.toObjectID(req.body.id)},
function (err, results) {
// log person in and send results to client
}
)
}),
signup: (function (req, res) {
var user = req.body;
req.db.collection('auth').insert(user, function (err, newUser) {
// after adding user, automatically log them in
// does not work:
//login(newUser, function (err) {
// do something
//})
// does not work:
this.login(newUser, function (err) {
// do something
})
}
)
})
}
Controllers should be doing as little as possible, and should orchestrate the work required by executing functions stored elsewhere.
View this gist - click here
What I have done is created "services" that are not tied to the client request, therefore re-usable everywhere.
Hope this helps.
Thanks to Dave Newton
var mongoskin = require('mongoskin');
var myCollection = 'auth';
Solution
function localLogin(db, myCollection, user, res){
db.collection(myCollection).findOne({_id: mongoskin.helper.toObjectID(user._id)},
function(err, user){
res.send({ token: createToken(user) });
});
module.exports = {
login: (function (req, res) {
var user = req.body;
localLogin(req.db, myCollection, user, res)
},
signup: (function (req, res) {
var user = req.body;
req.db.collection(myCollection).insert(user, function (err, newUser) {
// after adding user, automatically log them in
localLogin(req.db, myCollection, newUser, res)
})
}
) }) }

Resources