I'd like to use node.js to query a mySQL-database and return the results as JSON to be used in a mobile application. Unfortunately, my request just sorta times out and the server does nothing for a good 2 minutes until the log-files show my console.log()-statements.
Also, the callback doesn't return anything as result. It's just empty.
// Check dependencies
var http = require('http');
// Create the http server.
// reference: http://net.tutsplus.com/tutorials/javascript-ajax/node-js-for-beginners/
http.createServer(function(request, response) {
// Attach listener on end event.
request.on('close', function() {
console.log('request');
// run asynchronous
getSQL(function(err, result) {
console.log('json:', result);
response.writeHead(200, {
'Content-Type' : 'x-application/json'
});
// Send data as JSON string.
response.end(result);
});
});
}).listen(3000);
// Access MySQL via node-mysql
// https://github.com/felixge/node-mysql
function getSQL(callback) {
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'user',
password : 'pw',
database : 'db',
socketPath : '/var/run/mysqld/mysqld.sock', // socket for communication from debian <-> client, seems not to be set correcly by default?
});
connection.connect();
var json = '';
var query = 'SELECT * FROM test';
connection.query(query, function(err, results, fields) {
if (err)
return callback(err, null);
console.log('The result is: ', results[0]);
// wrap result-set as json
json = JSON.stringify(results);
});
connection.end();
callback(null, json);
};
Output after like 2 minutes:
$ node app.js
request
json:
The result is: { test: 'avc' }
json2: [{"test":"avc"}]
Based on my very basic understanding of the whole node.js-concept, my code should query the db (it does) and return a json once it's finished via the callback-function (apparently doesn't) which than is sent back as a response to the client (can't really check that since the json's empty).
I guess I made one (or a couple) major mistakes. Help and/or helpful links would be much appreciated. Thanks!
Solution, thanks to hexacyanide
// Check dependencies
var http = require('http');
// Create the http server.
// reference: http://net.tutsplus.com/tutorials/javascript-ajax/node-js-for-beginners/
/***************
* Correction 1: Using the request.on('close', function()( ... )-listener isn't required anymore
***************/
http.createServer(function(req, res) {
console.log('Receving request...');
var callback = function(err, result) {
res.writeHead(200, {
'Content-Type' : 'x-application/json'
});
console.log('json:', result);
res.end(result);
};
getSQL(callback);
}).listen(3000);
// Access MySQL via node-mysql
// https://github.com/felixge/node-mysql
function getSQL(callback) {
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'user',
password : 'pw',
database : 'db',
socketPath : '/var/run/mysqld/mysqld.sock', // socket for communication from debian <-> client, seems not to be set correcly by default?
});
connection.connect();
var json = '';
var query = 'SELECT * FROM test';
connection.query(query, function(err, results, fields) {
if (err)
return callback(err, null);
console.log('The query-result is: ', results[0]);
// wrap result-set as json
json = JSON.stringify(results);
/***************
* Correction 2: Nest the callback correctly!
***************/
connection.end();
console.log('JSON-result:', json);
callback(null, json);
});
};
You're following an older guide which instructs you to wait for the request's close event before sending the response, but you actually no longer need to do that.
What's happening is you aren't sending your response, so your client is timing out. Only until the client times out is when close events fires. Since the client has disconnected by the time you send your response, you don't get anything on the client and only see it in the terminal.
To fix this problem, just stop waiting for the close event and run code immediately when the request handler is called:
var http = require('http');
http.createServer(function(req, res) {
getSQL(function(err, result) {
res.writeHead(200, {
'Content-Type' : 'x-application/json'
});
res.end(result);
});
}).listen(3000);
Related
I'm new in Node JS and I'm trying to display the fetched data from my MySQL Table into a table in my HTML-File. But I couldn't find anything that helped me. I would really appreciate it if somebody can help me to get a solution! :)
Here's my js-code:
//app.js
// Get the mysql service
var mysql = require('mysql');
var express = require('express');
var app = express();
app.get('/', function (request , response) {
fetchData(response);
console.log('Done. Displayed Data.');
});
// Add the credentials to access your database
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'Breunninger',
port: '3306'
});
// connect to mysql
connection.connect(function(err) {
if(err){throw err;}
console.log('Connected');
});
function executeQuery(sql, cb){
connection.query(sql, function( result, fields){
cb(result);
})
}
function fetchData(response){
executeQuery("SELECT username, tor, datum, sendungsstruktur FROM Buchung JOIN user ON(user.id = Buchung.userid)", function (result) {
console.log(result);
response.write('<div class="container-wrap"><table id="example" class="display"><tr>');
for(var column in result[0]){
response.write('<td> <label>' + column + '</label></td>');
response.write('</tr>');
}
for(var row in result){
response.write('<tr>');
for(var column in result[row]){
response.write('<td>' + result[row][column]+ '</td>');
}
response.write('</tr>');
}
response.end('</table></div>');
});
}
<div class="container-wrap">
<div class="flexslider">
<script src="app.js"></script>
</div>
</div>
There's a small (but critical!) error in the executeQuery function, the first argument should be the error object, so if you can re-write this as below your query should work.
function executeQuery(sql, cb){
connection.query(sql, function( error, result, fields){
if (error) {
console.error("An error has occurred:", error);
} else {
cb(result);
}
})
}
Node callback usually reserve the first argument for an error object, it's easy to miss this!
Also, we should be clear, the Node.js Express code will be running on the server side, so to see the results you need to point your browser to the host and port this is serving, e.g. http://localhost:3000/ (if you do:)
app.listen(3000);
I want to load data from database as soon as page loads at front end, therefore I specified the route as '/' in GET. I am able to get the records in the console but my page doesn't load at http://127.0.0.1:3000. Here is a snap of the way I am creating server through node:
Yes I actually ran my server side through node app.js before creating this server
Moreover, even if it opens, and when I try to make a POST request to '/details' route, I get http 405 error. Here is a snap of my index.html where I am making an AJAX request:
In other ways, if I specify route as '/' in node Js and then make a request to '/', it inserts the record the way I want to.
I am quite new to AJAX and node Js. Can someone tell me where am I going wrong?
Here is my entire server side code:
const fetchOptions = {
headers: {
'Content-Type': 'application/json'
},
mode: 'cors'
};
var http=require("http");
var mysql=require("mysql");
var express=require('express');
var fs=require('fs');
var bodyParser=require('body-parser');
var app=express();
app.use(express.static('public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
console.log('Creating the http server');
var con= mysql.createConnection({
host: "localhost",
user: "root",
password: "root",
database: "budget_mgmt"
});
con.connect(function(err){
if(err)
{
console.log('Error connecting to db');
return;
}
console.log('Connection established');
});
var statement= "select * FROM budget_mgmt.item_description";
app.get('/',function(request,response)
{
fs.readFile('index.html',function(err,data)
{
console.log("The home page: index.html");
});
con.query(statement,function(error,results, fields)
{
if(error) throw error;
console.log(results);
response.end(JSON.stringify(results));
}); //response.end(data);
});
app.post('/details',function(request,response)
{
console.log(request.body);
console.log(request.body.description);
console.log(request.body.category);
console.log(request.body.amount);
console.log(request.body.date);
var sql = "INSERT INTO item_description(description,category,amount,today) VALUES ('"
+request.body.description+"','"+request.body.category+"',"+request.body.amount+","+"date_format(str_to_date('"+request.body.date+
"','%m-%d-%Y'),'%Y-%m-%d'));";
con.query(sql, function (err, result) {
if (err) throw err;
console.log("1 record inserted");
});
http.createServer(app).listen(3000,"127.0.0.1");
I am trying to retrieve data from a REST API in the server side (.js) and display it in my view (.jade)
I was able to get the data but was not able to send it to the view .
This is how my code looks like :
var BugData ='initial data' ;
var https = require('https');
var optionsget = {
rejectUnauthorized: false,
host : 'My host', // here only the domain name
// (no http/https !)
port : 443,
path : 'Mypath', // the rest of the url with parameters if needed
method : 'GET' // do GET
};
console.info('Options prepared:');
console.info(optionsget);
console.info('Do the GET call');
// do the GET request
var reqGet = https.request(optionsget, function(res) {
console.log("statusCode: ", res.statusCode);
res.on('data', function(d) {
console.info('GET result:\n');
BugData =d;
console.log('Show Data : ***** \n' +d);
});
});
reqGet.end();
reqGet.on('error', function(e) {
console.error(e);
});
res.render('index', { ab:BugData});
BugData (was defined before )is the variable i am trying to send to the view but for some reasons it is empty and does not contain the variable 'd'
Does anyone know why or how can i solve this ?
Thanks
There is no need to write that long code.
Be simple, follow these steps:
1) install request package:
npm install --save request
2) outside of router add:
var request = require('request');
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
3) use this code inside router:
request.get({url: 'https://my-host/Mypath'}, function(err, response, body) {
var data = {};
if (err) {
console.error(err);
data.err = err;
}
data.ab = body;
console.log('Data: ', data);
res.render('index', data);
});
I am using OpenShift and Node.js
I am trying to get the average - rating for each result but I cant
get the response to work even though the console reports correctly.
I get 3.9454323 into the console , but when I git localhost:3002/getM/1 the response is blank.
app.get('/getM/:movieId', function(request,response) {
var movieId = request.params.movieId;
var connection = mysql.createConnection({
host: process.env.OPENSHIFT_MYSQL_DB_HOST || 'localhost',
user: process.env.OPENSHIFT_MYSQL_DB_USERNAME || 'root',
password: process.env.OPENSHIFT_MYSQL_DB_PASSWORD || '',
port: process.env.OPENSHIFT_MYSQL_DB_PORT || '3306',
database: 'test'
});
connection.connect(function (err) {
if (err) {
console.error('error connecting: ' + err.stack);
response.send("error connecting to database");
return;
}
console.log('connected as id ' + connection.threadId);
});
connection.query('SELECT * FROM `ratings` WHERE `movieId` = ?',[movieId], function(err, result) {
if (err) {
response.send(err);
}
var sum = 0;
result.forEach(function(movie) {
sum += movie["rating"];
console.log(sum);
});
console.log(sum/result.length);
response.send(sum/result.length);
});
});
You are passing a numeric argument to response.send(). Here's what the express documentation says:
res.send([body])
Sends the HTTP response.
The body parameter can be a Buffer object, a String, an object, or an
Array.
see: http://expressjs.com/api.html
Try this:
response.send( "" + sum/result.length );
EDIT:
BTW, if you're using an older version of express, then express may be trying to interpret the number as an HTTP status code. I'm not sure what express will do with floating point values, but in any case that's clearly not what you intended.
Finally when a Number is given without any of the previously mentioned
bodies, then a response body string is assigned for you. For example
200 will respond will the text “OK”, and 404 “Not Found” and so on.
see: http://expressjs.com/3x/api.html#res.send
Hi I am currently trying to output mysql data to a browser window instead of the console, and I have not a clue on how to do this in Node, which I am quite new to.
Here is the mysql.js file:
'
var mysql = require ("mysql");
var connection = mysql.createConnection({
host:"localhost",
user: "root",
});
connection.connect(function (err) {console.log( "Successfully Connected.");
if (err) throw err;
});
var query = connection.query("SELECT * FROM myTable", function (err, result, fields){
if (err) throw err;
console.log('result:', result);
});
connection.end();'
You need to create a server which you can connect to and receive data from with a browser. The most convenient and by far the simplest way to do this is HTTP. You can read about HTTP servers in node.js here. The fist code snippet on that page demonstrates a HTTP server with one handler function, which is all you need to achieve your goal.
An (untested) example for convenience:
// Dependencies
var mysql = require("mysql"),
http = require("http");
// This holds our query results
var results;
// Connect to database
var connection = mysql.createConnection({
host: "localhost",
user: "root"
});
connection.connect(function(err) {
if (err) throw err;
console.log("Connected to database");
});
connection.query("SELECT * FROM myTable", function(err, rows, fields) {
if (err) throw err;
results = rows;
connection.end(); // Disconnect from database
});
// Function to handle browser's requests
function requestHandler(req, res) {
res.end(JSON.stringify(results)); // Respond to request with a string
}
// Create a server
var server = http.createServer(requestHandler);
// That magic number 8080 over here is the port our server listens to.
// You can access this webpage by visiting address http://localhost:8080
server.listen(8080, function() {
console.log("Server online");
});