I am building my first node.js server to perform a mysql query and return results from the database. Everything works but now I cannot find the right way to pass a value from the url (query section) to the function that performs the query (the PollingLoop function). No problems to retrieve the url and to get the parameter in the handler function but to move it to pollingLoop I have tried almost all I know about javascript (not enough I see). This is my code now that fails to run because of the reference error in pollingLoop for hwkey that is not defined.
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
url = require('url'),
fs = require('fs'),
mysql = require('mysql'),
connectionsArray = [],
connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'flipper',
database: 'oclock',
port: 3306
}),
POLLING_INTERVAL = 3000,
pollingTimer;
// If there is an error connecting to the database
connection.connect(function(err) {
// connected! (unless `err` is set)
if (err) {
console.log(err);
}
});
// creating the server ( localhost:8000 )
app.listen(8000);
function handler(req, res) {
console.log("INCOMING REQUEST: "+req.method+" "+req.url);
req.parsed_url = url.parse(req.url, true);
var getp = req.parsed_url.query;
var hwkey = getp.hk;
console.log(hwkey);
fs.readFile(__dirname + '/client.html', function(err, data) {
if (err) {
console.log(err);
res.writeHead(500);
return res.end('Error loading client.html');
}
res.writeHead(200);
res.end(data);
});
}
function pollingLoop(){
// Doing the database query
var query = connection.query('SELECT max(id), testo, created_by FROM flashmsgs WHERE hwk="'+hwkey+'"'),
//var query = connection.query('SELECT max(id), testo, created_by FROM flashmsgs'),
flashmsgs = []; // this array will contain the result of our db query
// setting the query listeners
query
.on('error', function(err) {
// Handle error, and 'end' event will be emitted after this as well
console.log(err);
updateSockets(err);
})
.on('result', function(flashmsg) {
// it fills our array looping on each user row inside the db
flashmsgs.push(flashmsg);
})
.on('end', function() {
// loop on itself only if there are sockets still connected
if (connectionsArray.length) {
pollingTimer = setTimeout(pollingLoop, POLLING_INTERVAL);
updateSockets({
flashmsgs: flashmsgs
});
} else {
console.log('The server timer was stopped because there are no more socket connections on the app')
}
});
};
// creating a new websocket to keep the content updated without any AJAX request
io.sockets.on('connection', function(socket) {
console.log('Number of connections:' + connectionsArray.length);
// starting the loop only if at least there is one user connected
if (!connectionsArray.length) {
pollingLoop();
}
socket.on('disconnect', function() {
var socketIndex = connectionsArray.indexOf(socket);
console.log('socketID = %s got disconnected', socketIndex);
if (~socketIndex) {
connectionsArray.splice(socketIndex, 1);
}
});
console.log('A new socket is connected!');
connectionsArray.push(socket);
});
var updateSockets = function(data) {
// adding the time of the last update
data.time = new Date();
console.log('Pushing new data to the clients connected ( connections amount = %s ) - %s', connectionsArray.length , data.time);
// sending new data to all the sockets connected
connectionsArray.forEach(function(tmpSocket) {
tmpSocket.volatile.emit('notification', data);
});
};
console.log('Please use your browser to navigate to http://localhost:8000');
just bring on hwkey variable out from handler
var hwkey;
function handler(req, res) { hwkey = ... }
pollingLoop(){console.log(hwkey);}
Related
I'm just getting started with Nodejs, so please bear with me
I store my DB setting on the first JS, connect.js :
var mysql = require('mysql');
module.exports = function(connectDB) {
var connectDB = {};
connectDB.connection = mysql.createConnection({
//db params
});
connectDB.connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connection.threadId);
});
return connectDB;
};
Then I stored my query in another JS file, lets call it dbManager.js :
var db = require('./connect')(connectDB);
var test_connection = connectDB.connection.query('SELECT * FROM `test`', function (error, results, fields) {
console.log(results);
});
exports.test = test_connection;
My goal is to pass the connection variable from connect.js to dbManager.js, so I could use it for running some queries.
The above code return an error, which said the variable is not passed successfully to dbManager.js :
ReferenceError: connectDB is not defined
Thanks in advance
The syntax error is because you cant define variables within an object literal using var.
e.g., you can't do the following,
var t = {
"r": 4,
var g = 5;
};
You can do this,
var t = {
"r": 4,
"g" : 5
};
And to access the properties of the object you can do,
console.log(t["r"]);
console.log(t.g);
In your code the problem is declaring a variable inside an object literal. Yo could do,
var connectDB = {};
connectDB.connection = mysql.createConnection({
//DB params
});
connectDB.connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connectDB.connection.threadId);
});
return connectDB;
Edit1 As per OP's comments,
connect.js:-
Changes- No need of the connectDB param, using module.exports functionality.
var mysql = require('mysql');
var connectDB = {};
connectDB.connection = mysql.createConnection({
//db params
});
connectDB.connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connectDB.connection.threadId);
});
module.exports = connectDB;
dbManager.js:-
var db = require('./connect');//removed the parameter
//use db variable to process queries as returned from the above require statement.
var test_connection = db.connection.query('SELECT * FROM `test`', function (error, results, fields) {
console.log(results);
});
exports.test = test_connection;
**you can do it like this
connection.js**
var mysql=require('mysql');
// Database Connection
var connection = mysql.createConnection({
host : hostname,
user :username,
password : password,
database : databasename,
multipleStatements:true
});
try {
connection.connect();
} catch(e) {
console.log('Database Connetion failed:' + e);
}
module.exports=connection;
**you can use this connection file in your dbmanager file like
this..**
var db = require('./connection.js');var test_connection =
connection.query('SELECT * FROM test', function(err,result) {
console.log(result);
});
Will something like this work for you? You can have a file that returns a connection object from the pool:
var mysql = require('mysql');
module.exports = function() {
var dbConfig = {...};
var database = mysql.createPool(dbConfig);
return {
getConnection: function(callback) {
// callback(error, connection)
database.getConnection(callback);
}
};
};
Wherever you need to use it, you can require it as follows:
var connector = require('./db-connector')();
Then use it like this:
connector.getConnection(function(error, connection) {
// Some code...
// Be sure to release the connection once you're done
connection.release();
});
This is how I store config data to pass around on my node server. I call it config.js and .gitignore it. I keep a sample copy called config.sample.js
let config = {};
config.mysql-host='localhost' || process.env.MYSQL_HOST;
config.mysql-user='me' || process.env.MYSQL_USER;
config.mysql-secret='secret' || process.env.MYSQL_SECRET;
config.mysql-database='my_db' || process.env.MYSQL_DB;
module.exports = config; //important you don't have access to config without this line.
To use it I would do the following.
const config = require('./config');
const mysql = require('mysql');
const connection = mysql.createConnection({
host: config.host,
user: config.user,
password: config.password,
});
connection.connect((err) => {
if(err) {
console.error(`error connecting: ${err.stack});
return;
}
console.log(`connected`);
});
const test_connection = connectDB.connection.query('SELECT * FROM `test`'(error, results, fields) => {
console.log(results);
});
I would like to be able to read data received by the ascii command sent.
Below is the code that sends command to my lock controller
var express = require('express');
var router = express.Router();
var SerialPort = require('serialport');
/* GET home page */
router.get('/', function(request, response){
SerialPort.list(function (err, ports) {
ports.forEach(function(port) {
console.log(port.comName);
console.log(port.pnpId);
console.log(port.manufacturer);
});
});
var port = new SerialPort("COM5", {
baudRate: 38400
});
port.on('open', function() {
// NodeJS v4 and earlier
port.write(new Buffer('status1', 'ascii'), function(err) {
if (err) {
return console.log('Error on write: ', err.message);
}
console.log('message written');
});
});
// open errors will be emitted as an error event
port.on('error', function(err) {
console.log('Error: ', err.message);
});
});
// Important
module.exports = router;
In the doc, it mentions the use of parsers to try and read data, https://github.com/EmergingTechnologyAdvisors/node-serialport#serialportparsers--object but I am not sure how to implement it, and I would want to execute after the command status1 has been written.
Essentially logs the response of the command succesfully written to the console
There are some peculiarities.
You can open port on application start and reconnect on port close or open port on each request. It defines how work with data flow. If you send request to port then answer can contain data of previous requests (more than one). You can ignore this problem (if answer is short and request interval is enough large) or send request with assign id and search answer with this id.
SerialPort.list(function (err, ports) {
ports.forEach(function(port) {
console.log(port.comName, port.pnpId, port.manufacturer); // or console.log(port)
});
});
router.get('/', function(req, res){
function sendData(code, msg) {
res.statusCode = 500;
res.write(msg);
console.log(msg);
}
var port = new SerialPort("COM5", {
baudRate: 38400
});
port.on('open', function() {
port.write(Buffer.from('status1', 'ascii'), function(err) {
if (err)
return sendData(500, err.message);
console.log('message written');
});
});
var buffer = '';
port.on('data', function(chunk) {
buffer += chunk;
var answers = buffer.split(/\r?\n/); \\ Split data by new line character or smth-else
buffer = answers.pop(); \\ Store unfinished data
if (answer.length > 0)
sendData(200, answer[0]);
});
port.on('error', function(err) {
sendData(500, err.message);
});
});
module.exports = router;
I have just made a simple program to display and insert data from a database(sql server 2008). My code does the display of data. I am unable to get data inserted. It shows no error in terminal or browser.
Here is my javascriptfile
var express = require('express');
var app = express();
app.use(express.static('public'));
app.get('/htm', function (req, res) {
res.sendFile( __dirname + "/" + "index.html" );
})
var sql = require("mssql");
var config = {
user: 'pkp',
password: 'pkp',
server: 'PRAVEEN\\SQLEXPRESS',
database: 'myneww'
};
app.get('/process_get', function (req, res) {
// Prepare output in JSON format
response = {
first_name:req.query.first_name,
last_name:req.query.last_name
};
sql.connect(config, function (err) {
if (err) console.log(err);
var request = new sql.Request();
console.log(req.query.first_name);
var res=request.query('insert into Mytab values(req.query.first_name ,req.query.last_name)');
});
});
app.get('/alldata', function (req, res) {
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('select * from Mytab', function (err, recordset) {
if (err) console.log(err)
// send records as a response
res.send(recordset);
});
});
});
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
Here is my html file
<html>
<body>
<form action="http://127.0.0.1:8081/process_get" method="GET">
First Name: <input type="text" name="first_name"> <br>
Last Name: <input type="text" name="last_name">
<input type="submit" value="Submit">
</form>
</body>
</html>
I am able to get the values displayed in the console, means values are passed and retrieved from the form. But still not inserted into the database.
I'm not good in javascript, but I guess the line below is incorrect:
var res=request.query('insert into Mytab values(req.query.first_name ,req.query.last_name)');
It should be something like this.
var res=request.query('insert into Mytab values(' + req.query.first_name + ',' + req.query.last_name +')');
If not, you've got an idea.
First, you were not passing values properly to query and, secondly, you are not waiting for the record to insert. Add the callback that I added.
app.get('/process_get', function (req, res) {
//some code
sql.connect(config, function (err) {
if (err) console.log(err);
var request = new sql.Request();
console.log(req.query.first_name);
request.query('insert into Mytab values('+req.query.first_name+','+req.query.last_name+')', function(err, recordset) {
if (err) {
console.log(err);
return res.send('Error occured');
}
return res.send('Successfully inserted');
});
});
});
Update
Use transaction to commit changes.
app.get('/process_get', function (req, res) {
//some code
var sqlConn = new sql.Connection(config);
sqlConn.connect().then(function () {
var transaction = new sql.Transaction(sqlConn);
transaction.begin().then(function () {
var request = new sql.Request(transaction);
request.query('Insert into EmployeeInfo (firstName,secondName) values ('+req.query.first_name+','+req.query.last_name+')').then(function () {
transaction.commit().then(function (recordSet) {
console.log(recordSet);
sqlConn.close();
return res.send('Inserted successfully');
}).catch(function (err) {
console.log("Error in Transaction Commit " + err);
sqlConn.close();
return res.send('Error');
});
});
});
});
Forgive me, if there is any typo.
I am new to node.js and am trying to learn how to connect to mysql database from ejs file. I tried to search for sample code however the code is not working. Can someone please check it out for me. Thank you.
function loaddata() {
var sql = require("mysql");
var con = mysql.createConnection({});
con.connect(function (err) {
if (err) {
console.log('Error connecting to Db');
return;
}
console.log('Connection established');
});
con.query('update students set name="sus" where email="smn14#mail.aub.edu"', function (err, rows) {
if (err) throw err;
console.log('Data received from Db:\n');
console.log(rows);
});
con.end(function (err) {
// The connection is terminated gracefully
// Ensures all previously enqueued queries are still
// before sending a COM_QUIT packet to the MySQL server.
});
}
The create connect is worst.
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function(err, rows,
fields) {
if (err) throw err;
console.log('The solution is: ', rows[0].solution); });
connection.end();
From this example, you can learn the following:
Every method you invoke on a connection is queued and executed in sequence.
Closing the connection is done using end() which makes sure all remaining queries are executed before sending a quit packet to the
mysql server.
Docs
I now understand the process of server/clients. Makes sense, otherwise you would be able to see the database passwords stored in Client.js. :-)
But, there is one way that works for me. The client call a javascript-function and send a message to the server. The server receives this message and starts a database query. Send the result to all clients via socket.io
At the client in the file.ejs
<script type='text/javascript'>
let socket = io.connect();
function getSql(userId) {
socket.emit('start-new-sql-querie',{
userId: userId
});
}
socket.on('new-sql-result', function (data){ // listen for the new sql result
console.log(data.userStatus); // foo something with the new data
})
</script>
<button onclick="getSql(1)">Test sql query</button>
database connection.js at server side
const connection = {
connectionLimit: 10,
host: "localhost",
user: "Abc",
password: "1234",
database: "d001",
multipleStatements: true
};
module.exports = connection;
yourapp.js at server side
const express = require('express');
const port = process.env.PORT || 1234;
const app = express();
const server = require('http').createServer(app);
const mysql = require('mysql2');
const config = require('./routes/connection'); // SQL-Connection
const pool = mysql.createPool(config);
let io = require('socket.io')(server);
io.sockets.on('connection', function(socket) {
socket.on('start-new-sql-querie', function(data) { // listen from the clients
let user_id = data.userId;
sql_test.getConnection((error, connection) => { // Connect to sql database
console.log("user_id: ", user_id)
connection.query(`SELECT * FROM user WHERE id='${user_id}'`, (err, result) => {
socket.emit('new-sql-result',{ // send sql result-status to all clients
userStatus: result.result[0].status
})
})
connection.release();
})
});
})
When i run my code i get an error
What i'm trying to do is when someone logs on to my site it logs the IP and other data into a database. it seems to work but then i get this error and it exits out of my app
{ [Error: Trying to open unclosed connection.] state: 1 }
Connection to database has been established
/home/azura/node_modules/mongoose/lib/index.js:343
throw new mongoose.Error.OverwriteModelError(name);
^
OverwriteModelError: Cannot overwrite `dataType` model once compiled.
at Mongoose.model (/home/azura/node_modules/mongoose/lib/index.js:343:13)
at Namespace.<anonymous> (/home/azura/Desktop/dbWrite.js:19:37)
at Namespace.EventEmitter.emit (events.js:95:17)
at Namespace.emit (/home/azura/node_modules/socket.io/lib/namespace.js:205:10)
at /home/azura/node_modules/socket.io/lib/namespace.js:172:14
at process._tickCallback (node.js:415:13)
The code that im using is:
var mongoose = require("mongoose");
var express = require("express");
var app = express();
var http = require("http").Server(app);
var io = require("socket.io")(http);
app.get("/", function (req, res) {
res.sendFile(__dirname + "/index.html");
});
io.on("connection", function (socket) {
var ip = socket.request.socket.remoteAddress;
var dataBase = mongoose.connection;
mongoose.connect("mongodb://localhost:27017/NEW_DB1");
dataBase.on("error", console.error);
console.log("Connection to database has been established");
var collectedData = new mongoose.Schema({
ipAddress: String,
time: Number
});
var collectionOfData = mongoose.model("dataType", collectedData);
var Maindata = new collectionOfData({
ipAddress: ip,
time: 100000000000000000
});
Maindata.save(function (err, Maindata) {
if (err) {
return console.error(err);
} else {
console.dir(Maindata);
}
});
});
http.listen(10203, function () {
console.log("Server is up");
});
the index.html file has nothing important on it.
I'm just wondering why i'm getting this error.
what can i do to fix it?
Put this code out of connection scope. No Need to create Schema every type there is new connection event.
mongoose.connect("mongodb://localhost:27017/NEW_DB1");
dataBase.on("error", console.error);
console.log("Connection to database has been established");
var collectedData = new mongoose.Schema({
ipAddress: String,
time: Number
});
var collectionOfData = mongoose.model("dataType", collectedData);
io.on("connection", function (socket) {
var ip = socket.request.socket.remoteAddress;
var dataBase = mongoose.connection;
var Maindata = new collectionOfData({
ipAddress: ip,
time: 100000000000000000
});
Maindata.save(function (err, Maindata) {
if (err) {
return console.error(err);
} else {
console.dir(Maindata);
}
});
});
every time a connection come in then the "connection" event will be emit,so
mongoose.connect("mongodb://localhost:27017/NEW_DB1");
will execute manny times,this cause the error.