Retrieving JSON response from local database - json

I am trying to print JSON response in my local browser of the data from my local system
I have my code::
var express=require('express');
var fs=require('fs');
var http=require('http');
var crypto=require('crypto');
var mysql=require('mysql');
var async=require('async');
var app=express();
var connection=mysql.createConnection({
host: 'localhost',
user: 'root',
database: 'ImagePostingDB'
});
connection.connect();
app.set('port',process.env.PORT||7002);
app.use('/Details',express.static(__dirname+'/public/images'));
app.use(express.bodyParser());
app.get('/DescriptionSortedPrice/',function(request,response){
var name_of_restaurants;
async.series( [
// Get the first table contents
function ( callback ) {
connection.query('SELECT * FROM ImagePostingtable ORDER BY Sl_no', function(err, rows, fields)
{
console.log('Connection result error '+err);
name_of_restaurants = rows;
callback();
});
}
// Send the response
], function ( error, results ) {
response.json({
'restaurants' : name_of_restaurants
});
});
});
http.createServer(app).listen(app.get('port'),function(){
console.log('Express server listening on port'+app.get('port'));
});
When i tried with postman:: i have no JSON response::
How to resolve this ?
or
how to find my root cause of the problem
{Edit}
var express=require('express');
var fs=require('fs');
var http=require('http');
var crypto=require('crypto');
var mysql=require('mysql');
var async=require('async');
var app=express();
var connection=mysql.createConnection({
host: 'localhost',
user: 'root',
database: 'ImagePostingDB'
});
connection.connect(function(err) { if ( !err ) { console.log("Connected to MySQL"); } else if ( err ) { console.log(err); } });
app.set('port',process.env.PORT||7002);
app.use('/Details',express.static(__dirname+'/public/images'));
app.use(express.bodyParser());
app.get('/DescriptionSortedPrice/',function(request,response){
connection.query('SELECT * FROM ImagePostingtable ORDER BY Sl_no', function(err, rows, fields) {
if (err) {
return response.send(500, err.message);
}
response.json({
'restaurants' : rows
});
});
});
http.createServer(app).listen(app.get('port'),function(){
console.log('Express server listening on port'+app.get('port'));
});
I have a Snapshot in my command prompt like this::

First: can you confirm that the server doesn't crash when you launch the request? A response code of 0 usually means that the connection was cut (or that no response was sent at all).
async.series is supposed to be used to call multiple asynchronous functions in series: there's no need to use it if you only call one function.
The callbacks in async.series follow Node.js's callback style, which means they take an error (or null) as a first parameter, and then the results of the function. But you don't send it any arguments: callback(). However, your code still works because you use a local variable name_of_restaurants that you overwrite in your asynchronous function. Be careful because that's not how you are supposed to use this pattern. Here is a more elegant solution:
app.get('/DescriptionSortedPrice/',function(request,response){
connection.query('SELECT * FROM ImagePostingtable ORDER BY Sl_no', function(err, rows, fields) {
if (err) {
console.log('Encountered an error:', err.message);
return response.send(500, err.message);
}
console.log('Found results:', rows);
response.json({
'restaurants' : rows
});
});
});

Related

Node.js, Mysql TypeError: Cannot read property 'apikey' of undefined

I am working on a basic auth middleware for a API it uses Node.js Mysql but if someone puts a incorrect key in auth header and sends the request the entire API crashes heres my code the issue is with the callback but I don't know how to fix that.
var express = require('express');
var app = express();
app.get('/', (request, response) => {
response.sendStatus(200);
});
let listener = app.listen(3000, () => {
console.log('Your app is currently listening on port: ' + listener.address().port);
});
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '127.0.0.1',
user : 'root',
database : 'systemdata'
});
connection.connect();
function systemAuth(apikey, callback)
{
connection.query('SELECT apikey FROM systemdata.systemkeys WHERE apikey = ?', [apikey], function(err, result)
{
if (err)
callback(err,null);
else
callback(null,result[0].apikey);
});
}
var auth = function (req, res, next) {
systemAuth(req.headers.apikey, function(err,data){
if (err) {
console.log("ERROR : ",err);
} else {
console.log("result from db is : ",data);
}
if(data == req.headers.apikey) {
next()
}else{
res.status(401).send({"error": "Missing or Invalid API-Key", "apikey": req.headers.apikey, "valid": "false"})
}
})
}
app.use(auth)
You will also have to check whether your result actually contains any rows.
A query not returning any rows is not an error, so err won't be set, if result is an empty array. And accessing an element by an index which does not exist leads to undefined, thus the error you are seeing.
function systemAuth(apikey, callback)
{
connection.query('SELECT apikey FROM systemdata.systemkeys WHERE apikey = ?', [apikey], function(err, result)
{
if (err) // some error with the query
callback(err,null);
else if (!result || result.length == 0) // no matching rows found
callback(new Error("invalid apikey"), null);
else // a matching row is found
callback(null,result[0].apikey);
});
}

nodejs mysql using data in other modules/files

I'm trying to get data from my DB and use it in different modules of my app. My app is split in a lot of modules which I require where I need them.
My connectDB.js module looks like this
var mysql = require('mysql');
var db = mysql.createConnection({
host: "localhost",
user: "root",
password: "pw",
database : "something"
});
db.connect(function(err){
if(err){
console.log('Error connecting to Db');
return;
}
console.log('Database connected');
});
function select(query)
{
db.query(query,function(err,rows){
if(err) throw err;
return rows;
});
}
module.exports =
{
select
}
I was hoping to simply just require this module and then do a something like
db.select('SELECT * FROM users');
But for some reason the return value is always "undefined"
Sending queries inside the connectDB module works as expected returning the correct data. But I can't use my function to get data.
Is there something wrong here with my logic? Can you help what I am doing wrong?
As I remember, connection.query will return result async, so you need to wrap it with callback or Promise.
var mysql = require('mysql');
function DB {
var db = mysql.createConnection({
host: "localhost",
user: "root",
password: "pw",
database : "something"
});
db.connect(function(err){
if(err){
console.log('Error connecting to Db');
return;
}
console.log('Database connected');
});
this.select = function(query, callback) {
db.query(query,function(err,rows){
if(err) throw err;
callback(rows);
});
}
//Promise version
this.selectPromise = function(query) {
return new Promise(function(resolve, reject){
db.query(query,function(err,rows){
if(err) reject(err);
resolve(rows);
});
});
}
}
module.exports = DB;
How to use:
var DB = require('your-module');
var db = new DB();
db.query('select * from table', function(result) {
console.log(result);
});
db.selectPromise('select * from table').then(function(result) {
console.log(result);
});
Make the following change to your code
module.exports =
{
select: select
}
And you forgot about callback function
function select(query, callback)
{
db.query(query,function(err,rows){
if(err) throw err;
return callback(rows);
});
}
Then you can pass a function like this:
db.select('SELECT * FROM users', function(rows) {
// Do stuff with rows
});

Node js call function, that access mysql database and returns json result, multiple times

I'm new to Node.js. I have a function 'getFromDb' that accesses a mysql database and returns a json file with some data. What if I have an array of query data and I want to call the same function through a for loop to get a json file for each element of the array?
var http = require('http');
http.createServer(function(req, res) {
console.log('Receving request...');
var callback = function(err, result) {
res.setHeader('Content-disposition', 'attachment; filename=' + queryData+ '.json');
res.writeHead(200, {
'Content-Type' : 'x-application/json'
});
console.log('json:', result);
res.end(result);
};
getFromDb(callback, queryData);}
).listen(9999);
function getFromDb(callback, queryData){
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'xxxx',
password : 'xxxx',
database : 'xxxx',
port: 3306
});
connection.connect();
var json = '';
var data = queryData + '%';
var query = 'SELECT * FROM TABLE WHERE POSTCODE LIKE "' + data + '"';
connection.query(query, function(err, results, fields) {
if (err)
return callback(err, null);
console.log('The query-result is: ', results);
// 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 could use the async library for node for this. That library has many functions that make asynchronous programming in NodeJS much easier. The "each" or "eachSeries" functions would work. "each" would make all the calls to mysql at once time, while "eachSeries" would wait for the previous call to finish. You could use that inside your getFromDB method for your array.
See:
https://github.com/caolan/async#each
var http = require('http'),
async = require('async');
http.createServer(function(req, res) {
console.log('Receving request...');
var callback = function(err, result) {
res.setHeader('Content-disposition', 'attachment; filename=' + queryData+ '.json');
res.writeHead(200, {
'Content-Type' : 'x-application/json'
});
console.log('json:', result);
res.end(result);
};
getFromDb(callback, queryData);}
).listen(9999);
function getFromDb(callback, queryData){
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'xxxx',
password : 'xxxx',
database : 'xxxx',
port: 3306
});
connection.connect();
var arrayOfQueryData = ["query1", "query2", "query3", "query4", "query5"];
var jsonResults = [];
async.each(arrayOfQueryData, function (queryData, cb) {
var data = queryData + '%';
var query = 'SELECT * FROM TABLE WHERE POSTCODE LIKE "' + data + '"';
connection.query(query, function(err, results, fields) {
if (err)
return cb(err);
console.log('The query-result is: ', results);
// wrap result-set as json
var json = JSON.stringify(results);
console.log('JSON-result:', json);
jsonResults.push(json);
cb();
});
}, function (err) {
connection.end();
// callbacks from getFromDb
if (err) {
callback(err);
}
else {
callback(null,jsonResults);
}
});
}
use async module. it is the best one. If u dont want to add new module try following;
var count = 0;
array.forEach(function(element) { //array of the data that is to be used to call mysql
++count; //increase counter for each service call
async.db.call(element, callback); //the async task
}
var data = [];
function callback(err, resp) {
--count;//subtract for each completion
data.push(resp)
if(count == 0) { //return data when all is complete
return data;
}
}
I would recommend the async module though. it is very good practice and useful.

Simple server handling routes and giving error nodejs mysql

I'm trying to write a simple server using nodejs and have the server ship back different queries and/or custom headers/responses based on the routes. However, in the getUsers() function the error keeps getting hit and printing the 'Error querying' to the console instead of printing the email rows. I know the server is connected fine, because I can return a query when I just use the db and return a query with createConnection only using the second example. Any help spotting the error is greatly appreciated. Thanks.
What I'm trying to get done:
var http = require('http');
var mysql = require('mysql');
var url = require('url');
var util = require('util');
var db = mysql.createConnection({
host : "*********",
user : "*********",
password : "*********",
port : '****',
database : '*********'
});
db.connect(function(err) {
console.log('connected');
if (err)
console.error('Error connecting to db' + err.stack);
});
function getUsers() {
db.query('SELECT * FROM users', function(err, rows, fields) {
if (err)
// changed console.error('Error querying');
console.error(err);
if (rows)
console.log('Rows not null');
for (var i in rows) {
console.log(rows[i].email)
}
});
}
var server = http.createServer(function(req, res) {
console.log(req.url);
if (req.url == '/signup') {
console.log("User signing up");
} else if (req.url == '/signin') {
console.log("User signing in");
} else if (req.url == '/new') {
console.log("User request new game");
getUsers();
}
//res.writeHead(200);
//res.end('Hello Http');
});
server.listen(3000);
// changed and commented out db.end();
What does work with querying the db:
var connection = mysql.createConnection({
host : "********",
user : "********",
password : "********",
port : '****',
database : '********'
});
connection.connect();
var queryString = 'SELECT * FROM users';
connection.query(queryString, function(err, rows, fields) {
if (err) throw err;
for (var i in rows) {
console.log('Users: ', rows[i].email);
}
});
connection.end();
The code has been updated with the changes, and the problem was I was closing the database. After changing the error logs as was suggested in the comments, this was the error received.
{ [Error: Cannot enqueue Query after invoking quit.] code: 'PROTOCOL_ENQUEUE_AFTER_QUIT', fatal: false }
I then commented out the
db.end()
and the queries were returned fine.
Thanks for the help.

ExpressJs render after an action

i'm testing ExpressJs and i have a problem.
var mysql = require('mysql');
var url = require('url');
var connection = mysql.createConnection({
host : 'localhost',
port : '8889',
user : 'root',
password : 'root',
database : 'test'
});
var results = '';
// INIT
exports.init = function(req, res) {
if (req.params.query == 'names') {
getByName(req, res);
} else {
res.send('Erreur');
}
}
getByName = function(req, res) {
currentUrl = url.parse(req.url);
getResult = req.params.suffix.split('+');
for (key in getResult) {
connection.query('SELECT * from testnode WHERE nom = "'+getResult[key]+'"', function(err, rows, fields) {
if (err) throw err;
results += JSON.stringify(rows[0]);
console.log(results);
});
}
res.render('api', {'results' : results});
}
When i go for the first time on the page this one is empty and if i refresh the result appear.
I don't know why the first time the variable "results" are empty so the console.log give me the good result.
Have you got any ideas ?
Thanks a lot :)
You error comes from the mix of a loop and a callback. Node.js is a non blocking IO library : the process doesn't wait for your mysql query to finish to continue to do other stuffs, so the callback with the results is executed (sometime) after the render.
You have multiple options, the one I use is https://github.com/caolan/async or call render once all the callback are done.
Or change your strategy:
getByName = function(req, res) {
currentUrl = url.parse(req.url);
getResult = req.params.suffix.split('+');
connection.query('SELECT * from testnode WHERE nom IN ("' + getResult.join('",") + '")', function(err, rows, fields) {
if (err) throw err;
var results = JSON.stringify(rows); //get all the results
res.render('api', {'results' : results});
});
}