I'm working with promises, or at least trying to.
Here is what my code look's so far:
checkEmailUsername = function(mail, user) {
return new Promise(function(resolve, reject) {
var query;
query = "SELECT * FROM users WHERE email = ? OR username = ?";
return connection.query(query, [mail, user], function(err, row, fields) {
if (err) {
reject(err);
}
console.log(row.length);
if (row.length > 0) {
return resolve(true);
} else {
return resolve(false);
}
});
}).then()["catch"]();
};
Question is. How to return the resolve values from inside the promise?
You can't use return here, use the promise resolve function to return the rows from db to the caller.
checkEmailUsername = function (mail, user) {
return new Promise(function (resolve, reject) {
var query;
query = "SELECT * FROM users WHERE email = ? OR username = ?";
connection.query(query, [mail, user], function (err, row, fields) {
if (err) {
reject(err);
}
console.log(row.length);
resolve(row);
});
};
checkEmailUsername(mail, user).then(function (rows) {
// do something with the rows
}).catch((err) => {
//handle error
}
}
Related
I am working on my first MySQL/ Nodejs project. I have the following lines of code that are working correctly.
async insertNewBrand(brand) {
try {
const dateAdded = new Date();
const insertId = await new Promise((resolve, reject) => {
const query = "INSERT INTO wines (brand, date_added) VALUES (?,?);";
connection.query(query, [brand, dateAdded] , (err, result) => {
if (err) reject(new Error(err.message));
resolve(result.insertId);
})
});
return {
id : insertId,
brand : brand,
dateAdded : dateAdded
};
} catch (error) {
console.log(error);
}
}
When I try to include a new parameter, the code breaks (new code below). Here I am trying to add varietal but adding that in all the needed locations seems to break the code.
async insertNewBrand(brand,varietal) {
try {
const dateAdded = new Date();
const insertId = await new Promise((resolve, reject) => {
const query = "INSERT INTO wines (brand, varietal, date_added) VALUES (?,?,?);";
connection.query(query, [brand, varietal, dateAdded] , (err, result) => {
if (err) reject(new Error(err.message));
resolve(result.insertId);
})
});
return {
id : insertId,
brand : brand,
dateAdded : dateAdded
};
} catch (error) {
console.log(error);
}
}
I am getting the error "Cannot read properties of undefined (reading 'insertId')". I am not sure what I am doing wrong. Any ideas?
There must be an error in the SQL, which is being reported by reject(err.message). When there's an error, you shouldn't try to use the result object. So use else so you either reject or resolve, but not both.
connection.query(query, [brand, varietal, dateAdded] , (err, result) => {
if (err) {
reject(new Error(err.message));
} else {
resolve(result.insertId);
}
})
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
var checkAcount = (usr, pass) => {
var sql = "SELECT * FROM account WHERE userName = '" +usr+"'" ;
con.query(sql, (err, result) => {
if(err) throw err;
if(result.length > 0){
bcrypt.compare(pass, result[0].password, function(err, result1) {
if(result1 == true){
return true;
}
else{
return false;
}
});
}
else {
return false;
}
});
return ???;
}
I have code like this and I don't know how to make this function return the value of the compare function (true or false). Add return in child function like I did seem not to work. Can somebody help me please.
You could return a promise:
async function checkAcount(usr, pass) => {
const sql = "SELECT * FROM account WHERE userName = ?" ;
return new Promise((resolve, reject) => {
con.query(sql, [usr], (err, result) => {
if(err) {
reject(err);
throw err;
}
if(result.length > 0){
bcrypt.compare(pass, result[0].password, function(err, result1) {
if(result1 == true){
resolve(result);
return true;
} else{
reject(err);
return false;
}
});
} else {
reject(err);
return false;
}
});
});
}
Don't build your SQL query with string concatenation. That allows SQL injection.
bcrypt returns a promise
https://www.npmjs.com/package/bcrypt#with-promises
bcrypt.compare(pass, result[0].password).then((result) => {
return result;
})
Please help me, I need to implement a function in a separate module file and in the route where the render has to call this function receiving the query data:
function getSobre() {
return new Promise((resolve, reject) => {
db.query(`SELECT * FROM sobre ORDER BY cod DESC LIMIT 1`, (err, results) => {
if (err) {
return reject(err);
} else {
return resolve(results);
}
});
});
}
const data = {
title: getSobre().then(data => {
/*
* HERE How do I return this "data" to the "title:" ?????????????
*/
}),
name: 'Fabio',
profession: 'Analista'
}
module.exports = data;
db.query is a Js callback . Which will wait for the result , then return anything.
So data will always be empty since it is getting returned much before db.query getting full resolved
You should wrap this in a native promise, and then resolve the promise :
function getTabela{
return new Promise(function(resolve, reject) {
// The Promise constructor should catch any errors thrown on
// this tick. Alternately, try/catch and reject(err) on catch.
let sql = "SELECT * FROM sobre ORDER BY cod DESC LIMIT 1";
var data = {};
db.query(sql, (err, results, fields) => {
if (results.length > 0) {
resolve(fields)
} else {
console.log('Erro: ' + err);
}
});
});
}
getTabela().then(function(rows) {
// now you have your rows, you can see if there are <20 of them
}).catch((err) => setImmediate(() => { throw err; }));
This way you should always have the data which is expected out of the query.
I am using mysql package from https://www.npmjs.com/package/mysql
So basically I have this function in a file:
module.exports.listGames = (id) => {
let query = 'SELECT * FROM test';
if (id) {
query += 'WHERE userid = ' + connection.escape(id);
}
connection.query(query, function(err, results) {
if (err) {
throw err;
}
console.log(results);
});
}
and I want to return those results in the json format
so I can call it in another file which is this function:
function sendGames(req, res) {
const games = db.listGames(req.query.game);
res.json(games);
}
so my question is, How can I return the results from that query?
You can either
Use callback
module.exports.listGames = (id, cb) => {
let query = 'SELECT * FROM test';
if (id) {
query += 'WHERE userid = ' + connection.escape(id);
}
connection.query(query, function(err, results) {
if (err) {
throw err;
}
cb(results);
});
}
module.exports.listGames(12, (results) => {
console.log(results);
})
Use promise
module.exports.listGames = (id) => {
let query = 'SELECT * FROM test';
if (id) {
query += 'WHERE userid = ' + connection.escape(id);
}
return new Promise((resolve, reject) => {
connection.query(query, function(err, results) {
if (err) {
throw err;
}
resolve(results);
});
})
}
module.exports.listGames(12).then(results => console.log(results)
You can encode the response from mysql query to JSON using JSON.stringify.
module.exports.listGames = (id) => {
let query = 'SELECT * FROM test';
if (id) {
query += 'WHERE userid = ' + connection.escape(id);
}
connection.query(query, function(err, results) {
if (err) {
throw err;
}
return (results);
});
}
Declare javascript async function and call the method from here.
async function sendGames (req, res) {
var games = await db.listGames(req.query.game);
res.json(games);
}
I'm trying to write a wrapper class called Mongo. When I call getCollection() inside insert(), but I'm getting 'TypeError: this.getCollection is not a function'.
const mongoClient = require('mongodb').MongoClient;
const connectionString = process.env.MONGODB_CONNECTION_STRING;
const mongoOptions = {
connectTimeoutMS: 500,
autoReconnect: true
};
function Mongo(dbName, collectionName) {
this.dbName = dbName;
this.collectionName = collectionName;
this.db = null;
this.collectionCache = {};
this.getDB = function () {
return new Promise(function (resolve, reject) {
if (this.db == null) {
mongoClient.connect(connectionString, mongoOptions, function (err, db) {
if (err) reject(err);
this.db = db.db(this.dbName);
resolve(this.db);
});
} else {
resolve(this.db);
}
});
};
this.getCollection = function () {
return new Promise(function (resolve, reject) {
if (this.collectionName in this.collectionCache) {
resolve(this.collectionCache[this.collectionName]);
} else {
getDB().then(function(db) {
db.collection(this.collectionName, function (err, collection) {
if (err) reject(err);
this.collectionCache[this.collectionName] = collection;
resolve(collection);
});
}, function (err) {
reject(err);
});
}
});
};
this.insert = function(docs) {
return new Promise(function (resolve, reject) {
this.getCollection().then(function(collection) {
collection.insert(docs, function(err, results) {
if (err) reject(err);
resolve(results);
});
});
}, function (err) {
reject(err);
});
}
}
module.exports = Mongo;
How this class is instantiated, and the insert method is called.
const assert = require('assert');
const Mongo = require('../data/mongo');
describe('MongoTest', function() {
it('TestInsert', function() {
var mongo = new Mongo('testdb', 'humans');
var testDoc = {
_id: 1100,
name: 'tommy',
tags: ['cool', 'interesting']
};
mongo.insert(testDoc).then(function(result){
assert.equal(result._id, 1100);
});
})
})
Where you're calling the getCollection function, this no longer refers to the Mongo object, it refers to the callback function you've passed as a parameter to the Promise.
There are many ways of fixing that. Here are a few:
Keeping a reference to the object:
this.insert = function(docs) {
var self = this;
return new Promise(function (resolve, reject) {
self.getCollection().then(function(collection) {
collection.insert(docs, function(err, results) {
if (err) reject(err);
resolve(results);
});
});
}, function (err) {
reject(err);
});
}
Binding the context:
this.insert = function(docs) {
var callbackFunction = function (resolve, reject) {
this.getCollection().then(function(collection) {
collection.insert(docs, function(err, results) {
if (err) reject(err);
resolve(results);
});
});
};
return new Promise(callbackFunction.bind(this), function (err) {
reject(err);
});
}
Update your insert function as follows -
this.insert = function(docs) {
var _self = this;
return new Promise(function (resolve, reject) {
_self.getCollection().then(function(collection) {
collection.insert(docs, function(err, results) {
if (err) reject(err);
resolve(results);
});
});
}, function (err) {
reject(err);
});
}
You are getting this error because you are calling getCollection inside callback function where this does not refer to Mongo class. So you need to store the Mongo class reference in a variable and then use it.