query results are undefined - javascript

exports.save = function(req, res) {
connection.query('INSERT INTO student_details(name, course, units, grades, gwa) VALUES(?, ?, ?, ?, ?)',[req.body.name,req.body.course,req.body.units,req.body.grades,req.body.gwa], function(err, row) {
if(err) res.send('Error in query');
selectOne(row.insertId, function(newRow){
if(err) res.status(554).send('Error in query');
if(newRow == null){
res.send(552, {message: 'Student Details ('+row.insertId+') was not created.'});
} else{
res.status(200).send(newRow);
}
});
});
}
var selectOne = function(id, callback){
connection.query('SELECT * FROM student_details WHERE id=? LIMIT 1', [id], function(err, rows){
if(err) return err;
if(rows.length != 0){
callback(rows[0]);
}else{
callback(null);
}
});
}
I'm having an error performing the query above. It's saying this error:
Uncaught TypeError: Cannot read property 'insertId' of undefined.
I've been trying to figure this out for hours now, and my hunch is that it's somewhat related to asynchronous values but I can't figure out how to fix it.
UPDATE:
This is my test file:
var studentdb = require(__dirname + '/../studentdb'),
student = require(__dirname + '/../student'),
index = require(__dirname + '/../index'),
should = require('should-http'),
assert = require('assert'),
request = require('supertest');
describe('Student Details', function() {
var url = 'http://localhost:1337';
var randomName = student.getRandomName(10);
var insertedId = 0;
describe('insert()', function () {
it('should create a new student record', function (done) {
var input = {
nameLength: 10,
subjectsLength: 5,
course: 'CAS'
};
studentName = student.getRandomName(input.nameLength);
studentCourse = student.getRandomCourse(input.course);
studentUnits = student.getRandomUnits(input.subjectsLength);
studentGrades = student.getRandomGrades(input.subjectsLength);
studentGWA = student.computeGWA(studentUnits, studentGrades,input.subjectsLength);
var stringUnits = studentUnits.join();
var stringGrades = studentGrades.join();
var generatedStudent = {
'name': studentName,
'course': studentCourse,
'units': stringUnits,
'grades': stringGrades,
'gwa': studentGWA
}
request(url)
.post('/addStudent')
.send(generatedStudent)
.end(function(err, res) {
if (err) {
throw err;
}
res.should.have.status(200);
res.body.should.have.keys(['id', 'name', 'course','units', 'grades', 'gwa']);
done();
});
});
});
describe('save()', function() {
console.log(insertedId);
it('should generate a student record', function(done) {
request(url)
.get('/generateStudent')
.end(function(err, res) {
if(err) throw err;
res.should.have.status(200);
res.body.should.not.have.property('name', null);
res.body.should.not.have.property('course', null);
generatedStudent = res.body;
done();
});
});
it('should not have duplicate name', function(done) {
request(url)
.get('/getStudents')
.end(function(err, res) {
if(err) throw err;
res.body.forEach(function(iteration) {
assert.notEqual(iteration, generatedStudent.name);
});
done();
});
});
it("now adding to the database", function(done) {
request(url)
.post('/addStudent')
.send(generatedStudent)
.end(function(err, res) {
if(err) throw err;
res.body.should.have.status(200);
console.log(res.body.id);
res.body.should.have.keys(['id', 'name', 'course', 'units', 'grades', 'gwa']);
done();
});
});
});
});
----------SECOND UPDATE after following Zeeshan's code------------------
they keep on rejecting my edit in the comment section.
Again, I've tried your suggestion but still no cigar. I've also printed the "newRow" to show that the data is being retrieved properly, it's just that when I try the res.send function, it is being read as undefined therefore causing the error. Thank you for your patience!
Server Connected on port: 1337
Student Details
insert()
Database is connected ... nn
If error, I should not be printed
Value of row.insertId 34
{ id: 34,
name: 'H3tno72Osk',
course: 'BS Computer Science',
units: '4,1,2,4,2',
grades: '3.0,3.0,3.0,3.0,4.0',
gwa: 3 }
✓ should create a new student record (66ms)
save()
✓ should generate a student record
✓ should not have duplicate name
1) now adding to the database
3 passing (90ms)
1 failing
1) Student Details save() now adding to the database:
Uncaught AssertionError: expected Object { body: undefined, statusCode: undefined } to have property statusCode of 200 (got undefined)
at Assertion.fail (node_modules/should/lib/assertion.js:92:17)
at Assertion.Object.defineProperty.value [as status] (node_modules/should/lib/assertion.js:164:19)
at Test.<anonymous> (test/studentdb.js:86:27)
at Test.assert (node_modules/supertest/lib/test.js:156:6)
at assert (node_modules/supertest/lib/test.js:127:12)
at node_modules/supertest/lib/test.js:124:5
at Test.Request.callback (node_modules/supertest/node_modules/superagent/lib/node/index.js:691:12)
at IncomingMessage.<anonymous> (node_modules/supertest/node_modules/superagent/lib/node/index.js:922:12)
at _stream_readable.js:920:16

Modified a bit, Can you try this as well and update with results?
exports.save = function(req, res) {
connection.query('INSERT INTO student_details(name, course, units, grades, gwa) VALUES(?, ?, ?, ?, ?)',[req.body.name,req.body.course,req.body.units,req.body.grades,req.body.gwa], function(err, row) {
if(err) return res.send('Error in query');
console.log("If Errror I should not pe printed");
console.log("Value of row.insertId ", row.insertId);
selectOne(row.insertId, function(newRow, insertId){
if(err) res.status(554).send('Error in query');
if(newRow == null){
res.send(552, {message: 'Student Details ('+insertId+') was not created.'});
} else{
res.status(200).send(newRow);
}
});
});
}
var selectOne = function(id, callback){
connection.query('SELECT * FROM student_details WHERE id=? LIMIT 1', [id], function(err, rows){
if(err) return err;
if(rows.length != 0){
callback(rows[0], id);
}else{
callback(null, id);
}
});
}

So, I have managed to get the result that I wanted. I ended up comparing the id count from the insert() function, instead of the save() function.
describe('insert()', function () {
it('should create a new student record', function (done) {
var input = {
nameLength: 10,
subjectsLength: 5,
course: 'CAS'
};
studentName = student.getRandomName(input.nameLength);
studentCourse = student.getRandomCourse(input.course);
studentUnits = student.getRandomUnits(input.subjectsLength);
studentGrades = student.getRandomGrades(input.subjectsLength);
studentGWA = student.computeGWA(studentUnits, studentGrades, input.subjectsLength);
var stringUnits = studentUnits.join();
var stringGrades = studentGrades.join();
var generatedStudent = {
'name': studentName,
'course': studentCourse,
'units': stringUnits,
'grades': stringGrades,
'gwa': studentGWA
}
request(url)
.post('/addStudent')
.send(generatedStudent)
.end(function(err, res) {
if (err) {
throw err;
}
res.should.have.status(200);
insertedId = res.body.id;
res.body.should.have.keys(['id', 'name', 'course', 'units', 'grades', 'gwa']);
done();
});
});
});

You should exec return if got err. The simplest way to do this is if(err) return res.send('Error in query');.

Related

Why do I get ReferenceError: insertId is not defined on my 4th MySQL Query in NodeJS?

Why am I able to get the insertId from the first MySQL query but not further on in the code on the fourth query? The query is somewhat complex, but I don't know why something which works the first time doesn't work later on in the code;
var mysql = require("mysql");
var express = require("express");
var connection = require("../database")
var createAudiopost = function(req, res, next){
var title = req.body.title;
var userid = req.body.userid;
var opid = req.body.opid;
var tag1 = req.body.tag1;
connection.beginTransaction(function(err) {
if (err) { throw err; }
connection.query('INSERT INTO ?? (title,userid,opid) VALUES (?, ?, ? )', ['audioposts',title,userid,opid], function(err, result) {
if (err) {
connection.rollback(function() {
throw err;
});
}
var audioname = userid + '-' + result.insertId + '.m4a';
var newid = result.insertId;
console.log("newid: " , newid );
connection.query('UPDATE ?? SET audioname=? WHERE audioid = ?', ['audioposts',audioname,newid], function (error, result, fields) {
if (err) {
connection.rollback(function() {
throw err;
});
}
if (tag1) {
connection.query('SELECT tagid FROM tags WHERE tagname = ?', [tag1], function (error, result, fields) {
if (err) {
connection.rollback(function() {
throw err;
});
}
if (result < 1) {
connection.query('INSERT INTO tags SET tagname = ?', [tag1], function (error, result, fields) {
if (err) {
connection.rollback(function() {
throw err;
});
}
console.log("lets see this wierd error", result);
const tagInsertId = result.insertId;
connection.query("INSERT INTO entitytag SET audioid = ?, tagid = ?, userid = ?", [insertId, tagInsertId, userId], function (error, result, fields) {
if (err) {
connection.rollback(function() {
throw err;
});
}
connection.commit(function(err) {
if (err) {
connection.rollback(function() {
throw err;
});
}
console.log('success!');
newid = result.insertId;
res.json({
"title" : title,
"userid" : userid,
"opid" : opid,
"insertid": newid
}); //resjson success
}); //commit
}); // insert entitytags
}); // insert tags
} // if row
else {
const tagid1 = result.tagid;
connection.query("INSERT INTO entitytag SET audioid = ?, tagid = ?, userid = ?", [insertId, tagid1, userId], function (error, result, fields) {
if (err) {
connection.rollback(function() {
throw err;
}); //err
} //err
connection.commit(function(err) {
if (err) {
connection.rollback(function() {
throw err;
});
}
console.log('success!');
res.json({
"title" : title,
"userid" : userid,
"opid" : opid,
"insertid": newid
}); //resjson success
}); //commit
}) // insert entitytag2
}
}); //select tagid
}//tag1
}); //update
}); //insert
}); //begin transaction
} //createaudiopost
module.exports = createAudiopost;
The code gets as far as;
sql: "INSERT INTO tags SET tagname = 'dogmatism'"
But then error I get straight afterwards is;
Parser.js:437
throw err; // Rethrow non-MySQL errors
^
ReferenceError: insertId is not defined
insertId is not defined but used in the following queries:
connection.query("INSERT INTO entitytag SET audioid = ?, tagid = ?, userid = ?", [insertId, tagid1, userId], function (error, result, fields)
Looks like you meant to use newid instead as per the usage in the query:
connection.query('UPDATE ?? SET audioname=? WHERE audioid = ?', ['audioposts',audioname,newid], function (error, result, fields)
Replace the same here and it should work.
connection.query("INSERT INTO entitytag SET audioid = ?, tagid = ?, userid = ?", [newid, tagid1, userId], function (error, result, fields)
If not create a variable called insertId and initialise it before using it.

UnhandledPromiseRejectionWarning: Error: Cannot enqueue Handshake after already enqueuing a Handshake

I am trying to create a node.js server that would handle a POST request that would have data into two different MySQL tables.
Here the code behind my node.js server.
let mysql = require("mysql");
const http = require('http');
http.createServer(async function(req, res) {
let con = mysql.createConnection({
host: "...",
user: "...",
password: "...",
database: "..."
});
res.writeHead(200, {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
});
if (req.method == 'POST') {
let body = '';
req.on('data', function(data) {
body += data.toString();
if (body.length > 10000000) {
http.request.connection.destroy();
}
});
req.on('end', () => {
if (body) {
let item = JSON.parse(body);
addQuestion(con, item.title).then(function(result){
con.end();
addOptions(con, result.insertId, item.options).then(function(data){
con.end();
res.end(JSON.stringify({
message: "Saved!"
}));
});
});
}
});
return;
}
res.end(JSON.stringify({
message: "OK!"
}));
}).listen(80);
function addQuestion(con, title) {
return new Promise((resolve, reject) => {
con.connect(function(err) {
if (err) return reject(err);
let sql = "INSERT INTO _questions SET ?";
con.query(sql, {title: title}, function(err, result, fields) {
if (err) return reject(err);
return resolve(result);
});
});
});
}
function addOptions(con, questionId, options) {
return new Promise((resolve, reject) => {
con.connect(function(err) {
if (err) return reject(err);
let values = [];
for(let x = 0 ; x < options.length; x++){
let option = options[x];
values.push({
title: option.title,
is_correct: option.isCorrect,
question_id: questionId
});
}
let optionsSql = "INSERT INTO _options (title, is_correct, question_id) VALUES ?";
con.query(questionSql, values, function(err, requestData) {
if (err) return reject(err);
return resolve(result);
});
});
});
}
I am getting the following error
UnhandledPromiseRejectionWarning: Error: Cannot enqueue Handshake
after already enqueuing a Handshake.
How can I solve this issue?
**If you using the node-MySQL module, just remove the .connect and .end. Just solved the problem myself.
**

Mongodb return old collection

router.post('/orders/finish', function(req, res, next) {
var order_id = req.body.order_id;
var user_id = req.body.user_id;
var table_id = '';
var result = [];
mongo.connect(url, function(err, db) {
assert.equal(null, err);
db.collection('tables').update({id: table_id, status: true}, {$set: {status: false}}, function(err, result) {
assert.equal(null, err);
});
var cursorTables = db.collection('tables').find({status: false});
cursorTables.forEach(function(doc, err) {
assert.equal(null, err);
result.push(doc);
}, function() {
db.close();
res.send(JSON.stringify(result));
});
});
I'm updating table collection and try to get them, but I get old collection without updating. However in the next request its changed.
When you make your .find() call, your collection isn't done updating yet.
You can choose to call .find() in the callback of your .update() call, or you could also use promises or async/await depending on your version.
Another solution would be to use findAndModify with the new option:
Optional. When true, returns the modified document rather than the original. The findAndModify() method ignores the new option for remove operations. The default is false.
You should wait for the update to complete before calling find
db.collection('tables').update({id: table_id, status: true}, {$set: {status: false}}, function(err, result) {
assert.equal(null, err);
var cursorTables = db.collection('tables').find({status: false});
cursorTables.forEach(function(doc, err) {
assert.equal(null, err);
resultTables.push(doc);
}, function() {
db.close();
});
});
I recommend you use Async
router.post('/', function(req, res) {
var order_id = req.body.order_id;
var user_id = req.body.user_id;
var table_id = '';
mongo.connect(url, table_id, function(err, db) {
myFuntion(db, table_id, function(result) {
res.send(JSON.stringify(result)); // it should be what you need
})
})
});
function myFuntion(db, table_id, callback) {
var result = [];
async.waterfall([
function(callback) {
db.collection('tables').update({id: table_id, status: true}, {$set: {status: false}}, function(err, result) {
assert.equal(null, err);
callback(null);
});
}, function(callback) {
db.collection('tables').find({status: false}, function(err, docs) {
docs.forEach(function(doc) {
result.push(doc);
})
callback(null, result);
});
}
], function(err, result) {
callback(result);
})
}

NodeJs check username and password return null

I'm trying to check the entered username and password stored in a database.
My solution is not correct and I think there might be something better than my code.
Here it is thus far:
function login (username, password, callback) {
var query = "SELECT * FROM users WHERE username = ?";
connection.query(query, [username], function (err, results) {
if (err) return callback(err);
if (results.length === 0) return callback();
var user = results[0];
if (!bcrypt.compareSync(password, user.password)) {
return callback();
}
callback(null, {
id: user.id.toString(),
});
});
}
app.get('/salam', function (req, res) {
var username = 'mahdi';
var originalPassword = 'a';
login(username , originalPassword,function (callback) {
console.log(callback);
});
});
In my code, console.log(callback); returns null, but usernames and passwords are correct. How can I fix this?
In your success callback function, you are having 2 arguments but in error callback, only one argument.
In error and success case, value of first parameter will always be null and in if (!bcrypt.compareSync(password, user.password)) { case, value of first argument will be undefined as there is no value being passed as argument.
Suggestion: Use first argument as Boolean(false or true) and based on the value, handle the callback.
function login(username, password, callback) {
var query = "SELECT * FROM users WHERE username = ?";
connection.query(query, [username], function(err, results) {
if (err) return callback(false);
if (results.length === 0) return callback();
var user = results[0];
if (!bcrypt.compareSync(password, user.password)) {
return callback(false);
}
callback(true, {
id: user.id.toString(),
});
});
}
app.get('/salam', function(req, res) {
var username = 'mahdi';
var originalPassword = 'a';
login(username, originalPassword, function(success, value) {
if (success) {
console.log(value);
}
});
});
It should be, because you didn't pass anything in callback. Change like this :
function login (username, password, callback) {
var query = "SELECT * FROM users WHERE username = ?";
connection.query(query, [username], function (err, results) {
if (err) return callback(err);
if (results.length === 0) return callback(null, false);
var user = results[0];
if (!bcrypt.compareSync(password, user.password)) {
return callback(null, false);
}
callback(null, true, {
id: user.id.toString(),
});
});
}
app.get('/check', function (req, res) {
var username = 'mahdi';
var originalPassword = 'a';
login(username , originalPassword,function (err, result, id) {
console.log(err);
console.log(result);
console.log(id);
});
});
result is for finding out true|false of action. And id means when result is true
Also err for callback is needed to error handling

Express JS res.redirect is undefined

I follow this tutorial on how to use passport-facebook in MEAN stack, I got this error when I try to use res.redirect('/signup') I always get this error: ReferenceError: res is not defined
it seems like I didn't pass res as a parameter in my function. I try to add it at second / last parameters. but nothing works. What do I miss???
Here is my code:
exports.saveOAuthUserProfile = function(req, profile, done){
User.findOne({
provider: profile.provider,
providerId: profile.providerId,
},
function(err, user) {
if (err) {
return done(err);
}
else
{
if (!user) {
// console.log(profile.email.value);
var possibleUsername = profile.username || ((profile.email) ? profile.email.value.split('#')[0] : '');
User.findUniqueUsername(possibleUsername, null, function(availableUsername){
profile.username = availableUsername;
user = new User(profile);
user.save(function(err){
if (err) {
var message = getErrorMessage(err);
// var message = _this.getErrorMessage(err);
req.flash('error', message);
return res.redirect('/register');
}
return done(err, user);
});
});
}
else
{
return done(err, user);
}
}
});
};

Categories

Resources