Node.js: Can't access mysql within createServer? - mysql

I'm trying to build a server in node.js that'll take a request from a client, access a mysql server on the server, and send data from that server to the client. I am able to access the mysql server outside of the createServer but I can't put the sql query within the createServer method.
Example of what doesn't work:
var jellies;
http.createServer(function (req, res) {
var sql = "SQL STATEMENT";
sqlConnection.query(sql, function(err, result) {
if (err) throw err;
jellies = result;
}
res.write(JSON.stringify(jellies));
}).listen(port);
Example of what does work:
var jellies;
var sql = "SQL STATEMENT";
sqlConnection.query(sql, function(err, result) {
if (err) throw err;
jellies = result;
}
http.createServer(function (req, res) {
res.write(JSON.stringify(
}).listen(port);
console.log(jellies) after the query is made produces null for the first function. Are you just not allowed to do anything in http.createServer()? Any ideas to work around this?
The error I get is: TypeError: First argument must be a string or Buffer. It calls back the the line for htts.createServer();

Can you please try this?
http.createServer(function (req, res) {
var sql = "SQL STATEMENT";
sqlConnection.query(sql, function(err, result) {
if (err) throw err;
res.write(JSON.stringify(result));
}
}).listen(port);

Figures the problem I worked on all yesterday would get solved by a friend online in a few seconds.
For the next person that might struggle with this all that needs to be fixed is moving res.write() and res.end() into the sql query function.

Related

having issues calling a sql stored procedure, SelectById, from express

I'm trying to call a saved stored procedure from SQL in my node app. my server is connected and I am able to execute my selectRandom5 saved proc with no problems.
the issue I am having is when I try to do a getById where I need to declare the #Id input. I've tried a couple of variations of the function with no luck, here are two I've tried.
the error message I get with this is UnhandledPromiseRejectionWarning: RequestError: Incorrect syntax near '?'.
selectById(req, res) {
var theId = req.params.id;
// connect to your database
sql.connect(config, function (err) {
if (err) console.log(err);
// create Request object
var request = new sql.Request();
// query to the database and get the records
request.query("CALL Addresses_SelectById(?)", [theId], function (err, recordset) {
if (err) console.log("connect", err);
// send records as a response
res.send(recordset);
console.log(recordset);
});
});
}
and then there's this other function I've tried, and the error message I get from this is 'Must declare the scalar variable "#Id".'
selectById(req, res) {
var theId = req.params.id;
// connect to your database
sql.connect(config, function (err) {
if (err) console.log(err);
// create Request object
var request = new sql.Request();
// query to the database and get the records
request.query(`SET #Id = ${theId}CALL Addresses_SelectById(#Id)`, function (err, recordset) {
if (err) console.log("connect", err);
// send records as a response
res.send(recordset);
console.log(recordset);
});
});
}
I just want to be able to pass parameters to SQL to be able to create update or get by but so far I haven't been able to figure out the proper way to pass the parameters.
any help would be appreciated! thanks guys
I FOUND IT GUYS!
selectById(req, res) {
var theId = req.params.id;
// connect to your database
sql.connect(config, function (err) {
if (err) console.log(err);
// create Request object
var request = new sql.Request();
// query to the database and get the records
request.input("Id", sql.Int, theId);
request.execute("Addresses_SelectById", function (err, recordset) {
if (err) console.log("connect", err);
// send records as a response
res.send(recordset);
console.log(recordset);
});
});
I changed it to this and it works
Problem 1:
Suggested alternate syntax:
selectById(req, res) {
var theId = req.params.id;
let sql = `CALL Addresses_SelectById(?)`;
connection.query(sql, theId, (error, results, fields) => {
if (error) {
return console.error(error.message);
}
console.log(results[0]);
// Possibly stringify "results" to JSON before sending...
res.send(results);
});
}

Node Express MySQL multiple routing

I want to make an route with multiple parameters using Node Express MySQL. Is it possible to do this with traditional url parameters like: page?id=2&user=10
Here is a simple query, but the only way of doing it so far is like this: page/2/10
app.get("/get-page/:id/:user", function (req, res) {
let sql = "SELECT * FROM table WHERE id= '${req.params.id}' AND userid= '${req.params.user}'`;";
let query = db.query(sql, (err, results) => {
if (err) throw err;
res.send(results);
});
});
This is just an example.
The reason I would like the traditional way is because, with the "slash" method the parameters always have to come in the correct order, or did I miss something?
Perhaps use the query property of the request to access the query string, as in req.query.id:
app.get("/get-page", function (req, res) {
console.log('ID: ' + req.query.id)
});

nodejs res.end not working in callback

I'm trying to retrieve data from a database and send it back to the user, but since mysql queries work asynchronously, I can't just put the code that sends the response after the query code, I have to send the response within the callback function of the query.
var express = require('express');
var fs = require('fs');
var mysql = require('mysql')
var app = express();
var con = mysql.createConnection({
host:"localhost",
user:"root",
password:"",
database:"tempdb"
})
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT,
PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-
type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.get('/',function(req,res,next){
function foo(res){
con.query('SELECT * FROM `data` WHERE 1',function(err,result){
if (err) throw err;
res.end('weee',function(err){
if (err) throw err;
)}
})
}
foo(res)
next();
})
app.listen(1001)
Even with something as simple as this, when the data from the database isn't processed or used at all, the res.end function doesn't send any data.
I've tried many variations of this, using waterfall callbacks, putting the res.end in a function outside of the query and calling it, but nothing seems to work. The only time it works it when I put it outside the query, but since the query is async I can't get any data out of it that way. Is there a way to work around this or am I just missing something?
Thanks in advance!
Remove the call to next() in your app.get() handler.
You only want to do that when you are NOT handling the request and sending a response and you want to let other handlers have a crack at the request.
The way you have it, you are calling next() BEFORE the con.query() finishes so that lets the default handler in express handle the request and thus your res.end() doesn't actually do anything because a response has already been sent for this request.
Here's what I would suggest:
app.get('/', function(req, res){
con.query('SELECT * FROM `data` WHERE 1',function(err, result){
if (err) {
console.log(err);
res.status(500).end();
} else {
res.send('weee');
}
});
});
So, you only call next() if you are not going to be sending a response and you want someone else in the handler chain to send the response.
When using res in middlewares throw a return before res.
app.get('/',function(req,res,next){
function foo(res){
con.query('SELECT * FROM `data` WHERE 1',function(err,result){
if (err) throw err;
return res.end('weee',function(err){
if (err) throw err;
)}
})
}
foo(res)
next();
})
Hopefully this works...

Store mysql query rows in variable for later use

I'm doing a monitoring system project in which I have Arduino sensors data being sent to a node.js server (thru GET requests) and then stored in a MySQL DB.
Whenvever I successfully send data to the server, it connects to the MySQL DB and queries the last 5 received records to do some processing.
Therefore, I need to store the rows of those 5 records in a variable for later use. Meaning that I have to get rows from a connection.query in a variable.
I read that the fact that I'm not able to do this is because node.js being async. So my questions are:
Is it possible to do the described tasks the way I'm trying?
If not, is there any other way to do so?
I'm not putting the whole code here but I'm running a separated test that also doesn't run properly. Here it is:
var mysql = require('mysql');
var con = mysql.createConnection({
host : "127.0.0.1",
user : "root",
password: "xxxx",
database: "mydb",
port : 3306
});
var queryString = "SELECT id, temp1, temp2, temp3, temp4, level_ice_bank, flow FROM tempdata ORDER BY id DESC LIMIT 5";
con.connect(function(err) {
if (err) throw err;
});
var result_arr = [];
function setValue (value) {
result_arr = value;
}
con.query(queryString, function (err, rows, fields) {
if (err) throw err;
else {
//console.log(rows);
setValue(rows);
}
});
console.log(result_arr);
It logs:
[]
But if I uncomment console.log(rows); it logs what I need to store in the variable result_arr.
Thanks in advance to all.
You're seeing this behaviour because con.query(...) is an asynchronous function. That means that:
console.log(result_arr);
Runs before:
con.query(queryString, function (err, rows, fields) {
if (err) throw err;
else {
//console.log(rows);
setValue(rows);
}
});
(Specifically, the setValue(rows) call)
To fix this in your example, you can just do:
con.query(queryString, function (err, rows, fields) {
if (err) throw err;
else {
setValue(rows);
console.log(result_arr);
}
});
If you want to do more than just log the data, then you can call a function which depends on result_arr from the con.query callback, like this:
con.query(queryString, function (err, rows, fields) {
if (err) throw err;
else {
setValue(rows);
doCleverStuffWithData();
}
});
function doCleverStuffWithData() {
// Do something with result_arr
}

Node Mysql Cannot Enqueue a query after calling quit

where do i close the mysql connection?
I need to run queries in sequence. I am writing code that looks like this at present:
var sqlFindMobile = "select * from user_mobiles where mobile=?";
var sqlNewUser = "insert into users (password) values (?)";
//var sqlUserId = "select last_insert_id() as user_id";
var sqlNewMobile = "insert into user_mobiles (user_id, mobile) values (?,?)";
connection.connect(function(err){});
var query = connection.query(sqlFindMobile, [req.body.mobile], function(err, results) {
if(err) throw err;
console.log("mobile query");
if(results.length==0) {
var query = connection.query(sqlNewUser, [req.body.password], function(err, results) {
if(err) throw err;
console.log("added user");
var user_id = results.insertId;
var query = connection.query(sqlNewMobile, [user_id, req.body.mobile], function(err, results) {
if(err) throw err;
console.log("added mobile");
//connection.end();
});
});
}
});
//connection.end();
(I am a beginner with node, npm-express and npm-mysql. I have tried searching SO for "express mysql cannot enqueue" to find related questions and have not found them.)
I fixed this problem use this method:
connection.end() in your connection.query function
The fixed code is here
If you're using the node-mysql module by felixge then you can call connection.end() at any point after you've made all of the connection.query() calls, since it will wait for all of the queries to finish before it terminates the connection.
See the example here for more information.
If you're wanting to run lots of queries in series, you should look into the async module, it's great for dealing with a series of asynchronous functions (i.e. those that have a callback).
Maybe the problem is that the mySQL query is executed after the connection is already closed, due to the asynchronous nature of Node. Try using this code to call connection.end() right before the thread exits:
function exitHandler(options, err) {
connection.end();
if (options.cleanup)
console.log('clean');
if (err)
console.log(err.stack);
if (options.exit)
process.exit();
}
//do something when app is closing
process.on('exit', exitHandler.bind(null, {cleanup: true}));
Code adapted from #Emil Condrea, doing a cleanup action just before node.js exits
In my case connection.end was being called in a spot that was hard to notice, so an errant call to connection.end could be the problem with this error