require function doesn't work inside a function within a method - node.js

I'm using Node.js to build the back-end of an application and I'm using postgresql as database. I'm having problem with the implementation of the login. More precisely I am using the bcrypt module and it doesn't work in the function called by the execution of the query. Here is the code:
const login = async (request, response) => {
const username = request.body.username
console.log(request.body)
pool.query('SELECT * FROM public."User" WHERE username = \'{' + username + '}\'', (error, results) => {
if (error) {
return response.status(400).send("Cannot find user: "+username)
}
try {
if(await bcrypt.compare(request.body.password, results.rows[0].password.toString())) {
response.send('Success')
} else {
response.send('Not allowed')
}
} catch {
response.status(500).send("Server error")
}
})
}
The problem is that I execute my query and it works, but when it arrives in the second if statement the problem is this:
if(await bcrypt.compare(request.body.password, results.rows[0].password.toString())) {
^^^^^^
SyntaxError: Unexpected identifier
I cannot figure out how to solve it.

I've also tried to take the try/catch statement outside the pool.query function, by saving the retrieved password in a variable, as follows:
const login = async (request, response) => {
const username = request.body.username
var hashedPassword
console.log(request.body)
pool.query('SELECT * FROM public."User" WHERE username = \'{' + username + '}\'', (error, results) => {
if (error) {
return response.status(400).send("Cannot find user: "+username)
}
hashedPassword = results.rows[0].password.toString()
})
try {
if(await bcrypt.compare(request.body.password, hashedPassword)) {
response.send('Success')
} else {
response.send('Not allowed')
}
} catch {
response.status(500).send("Server error")
}
}
But in this way the try/catch statement is executed before the query and actually I don't even know if variable "hashedPassword" can be set in such a way, because I always find it as "undefined"

Related

Node postgres query returning undefined instead of query result

I am creating a query to my postgres database. The function that makes the query looks like this:
const { pool } = require("./database");
async function getClasses(user) {
return pool.connect(async function (err, client, done) {
if (err) {
console.log(err);
} else {
const sqlText = `SELECT * FROM "public"."classes" WHERE "admins" = $1`;
const values = [user];
let listOfClasses = await client.query(sqlText, values);
done();
console.log(listOfClasses.rows);
return listOfClasses.rows;
}
});
}
module.exports = { getClasses };
The console.log(listOfClasses.rows) has the rows that I am looking for my function to return, but the actual returned value is undefined. I've been tinkering with the code for quite a while now and can't seem to figure it out. Any help here would be much appreciated.
You have to use the promise style api as the callback style call will not return anything (Your function is retuning client.connect(() => { ... }) which return undefined)
const getClasses = (...) => {
const client = await pool.connect()
const listOfClasses = await client.query(...);
return listOfClasses.rows;
}
should do

Why is my return variable value not being recognised in node module

I have got a node file requesting a return variable from another module page. All the data functions "work" but the "return query" is not sending the query value back to my initial request and my existingUser variable is undefined. In the console logs checks I put in the existingUser ones displays before the query one. It is like the await request is being ignored.
Any help appreciated...and I'm a newbie to all this!
Request page -
const sqlRequests1 = require('./sqlAdmin/sqlRequests1');
.
.
.
app.post('/', async (req, res) => {
const { club, first_name, last_name, email, tel, address, post_code, password, passwordConfirmation} = req.body;
let existingUser = await new sqlRequests1.Queries('contact',email).getAll();
console.log(`existingUser is ${existingUser}`); //THIS CONSOLE LOG RETURNS "undefined"
if (existingUser) {
return res.send('Email in use');
}
if (password !== passwordConfirmation) {
return res.send('Passwords must match');
}
res.send('Account created!!!');
});
Module page - sqlRequests1
class Queries {
constructor(table, selection) {
this.table = table;
this.selection = selection;
console.log(selection); //THIS DATA CHECK WORKS
if(!table) {
throw new Error('Need a table to connect to');
};
};
getAll() {
//Confirm if the emasil exists - if it does then give error message
let q = 'SELECT * FROM ?? ';
connection.query(q, this.table, function (error, results,fields) {
if (error) throw error;
const query = (results[0].email);
console.log(`query is ${query}`); //THIS PROVIDES THE CORRECT DATA
return query; //THIS RETURN IS NOT GETTING BACK TO existingUser variable?
});
};
};
module.exports.Queries = Queries;
If you want to use await and block the code from moving further, you have to convert your get all function to return a promise....
getAll() {
new Promise((resolve,reject) => {
//Confirm if the emasil exists - if it does then give error message
let q = 'SELECT * FROM ?? ';
connection.query(q, this.table, function (error, results,fields) {
if (error) reject(error);
const query = (results[0].email);
console.log(`query is ${query}`); //THIS PROVIDES THE CORRECT DATA
resolve(query) //THIS RETURN IS NOT GETTING BACK TO existingUser variable?
});
})
}
Promise was the way to go but it just missed the return
getAll() {
return new Promise((resolve,reject) => { //ADDING return here fixed it
//Confirm if the emasil exists - if it does then give error message
let q = 'SELECT * FROM ?? ';
connection.query(q, this.table, function (error, results,fields) {
if (error) reject(error);
const query = (results[0].email);
console.log(`query is ${query}`); //THIS PROVIDES THE CORRECT DATA
resolve(query) //THIS RETURN IS NOT GETTING BACK TO existingUser variable?
});
})
}

Variable cannot be change inside findOne

I want to make a quick Util file which would contain multiple functions such as an user_id to his name. As the image under shows, I tried to save the value throughout the code but the variable "name" doesn't get affected inside the .then(user => {}) for some reasons
I tried returning directly the value without using variable to save it.
I debugged and code runs fine and it gets into the if(!user){}else{}perfectly.
The user returned by Mongoose works and I can console log the user.username (Cannot return it, either can I save it to a variable, which is what i'm doing on the code under)
const User = require('../models/users')
exports.id2name = (id) => {
let name = 'none'
User.findOne({_id: id}).then(user => {
if (!user) {
name = 'Unknown'
} else {
name = user.username
}
}).catch(err => console.log(err))
return name
}
I don't get any errors on my console. It is returning 'none' as a result even if it gets into the else statement inside the mongoose request.
You are getting this result for asynchronous behaviours of JavaScript.
You can try this code for getting the desired result.
exports.id2name = async (id) => {
try{
let name = 'none'
const user = await User.findOne({_id: id});
if(user) {
name = user.username;
} else {
name = 'Unknown';
}
return name;
} catch(e) {
console.log(e);
}
}
It's asynchronous return. I mean you may need to use callback, Promise or other asynchronous way to deal with it, for example:
const User = require('../models/users')
exports.id2name = (id, callback) => {
User.findOne({_id: id}).then(user => {
if (!user) {
callback(null, 'Unknown')
} else {
callback(null, user.username)
}
}).catch(callback)
}
or promise:
const User = require('../models/users')
exports.id2name = (id) => {
return new Promise((resolve, reject) => {
User.findOne({_id: id}).then(user => {
if (!user) {
resolve('Unknown')
} else {
resolve(user.username)
}
}).catch(reject);
});
}

Ignoring exception from a finished function

I keep getting this error when this function executes.
Ignoring exception from a finished function
What I'm I missing?
exports = module.exports = functions.database.ref('/cards/{userId}/{id}')
.onCreate((snap, context) => {
const token = snap.val().token;
const userId = context.params.userId;
const stripeRef = admin.database().ref('/stripe').child(userId);
return stripeRef.once('value').then(function(snapshot) {
let accountId = snapshot.val().accountId;
return stripe.accounts.createExternalAccount(
accountId,
{ external_account: token },
function(err, card) {
snap.ref.child('cardId').set(card.id);
});
});
});
use try and catch to log the errors manually, like
try {
//code goes here
}
catch(error) {
console.log(error)
}

How can I get a value returned from a then clause when select data using mysql

I am trying to finish a login functionality with mysql and express. I got a work_id and a user_password, and I want to use the work_id to find whether the user exists in my database. I use promise to do this, I can log the selected user information in the console, but the promise is always pending, and the web storm console didn't terminate.
What I want is a boolean value from the promise, whether the user exists or not.
Here is my code:
query.js.
const pool = require('./connect');
module.exports = {
query: function (sqlString, params) {
return new Promise((resolve, reject) => {
pool.getConnection(function (err, connection) {
if (err) {
reject(err)
} else {
connection.query(sqlString, params, (err, rows) => {
if (err) {
reject(err)
} else {
resolve(rows)
}
connection.release()
})
}
})
})
}
}
sqlCRUD.js, about the sql statement
const user = {
queryByWorkId: 'select * from user_info where work_id=?',
queryAll: 'select * from user_info',
resetPassword: 'update user_info set user_password = ? where work_id = ?',
};
user.js, I execute the test here.
const Model = require('./main')
const crypto = require('crypto')
const _ = require('./query')
const $sqlQuery = require('./sqlCRUD').user
class User{
// others
static findOne(form={}) {
const { work_id, user_password } = form
return _.query($sqlQuery.queryByWorkId, work_id)
.then(res => {
console.log(res)
if (res.length > 0) {
const u = res[0]
return u
}
return false
})
.catch(err => {
console.log('User.findOne error', err)
return {
errmsg: JSON.stringify(err)
}
})
}
Here is my test, in user.js
const test = () => {
const form = {
work_id: '007',
user_password: 'root',
}
const r = User.findOne(form)
console.log('r', r)
}
And this is the output:
I am not allowed to embed a picture here, so SO generates a link
I got confused about this: in my query.js file, I return a promise, in my User.findOne(form={}) method, I call it with a then and catch,
return _.query($sqlQuery.queryByWorkId, work_id).then(res => console.log(res)).catch(err => console.log(err)), but the console did't terminate, and I just got a Promise { }.
What's wrong with my code? How can I get a value returned from a then clause in promise when select data using mysql? Thanks in advance.

Resources