I'm using a networking website in node using express and postgresql - using the pg npm module - as my database.
I'm now trying to setup user pages like this:
...
app.get('/u/:u/', function (req, res) {
pool.connect(function(err, client, done) {
...
client.query('SELECT * FROM users WHERE id =($1)', [req.params.u], function(err, result) {
... done(); ...
});
});
});
...
req.params.u returns undefined inside the DB query.
I assume it's because the call back function isn't in the same scope as the app route, how do I get about checking the database like this?
I have a feeling there's a much better way of doing this.
So if the problem is that params gets undefined, the solution should come from something similar to:
...
app.get('/u/:u/', function (req, res) {
var tempReq = req
pool.connect(function(err, client, done) {
...
client.query('SELECT * FROM users WHERE id =($1)',[tempReq.params.u], function(err, result) {
... done(); ...
});
});
});
...
Make sure to put your body-parser code above all the routes in your app.js file to get req.body or req.params or req.query value
var app=express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
And your req object is available in your whole route's scope then you can use it in any where in this block no need to store in local variable
app.get('/u/:u/', function (req, res) {
pool.connect(function(err, client, done) {
...
client.query('SELECT * FROM users WHERE id =($1)',[req.params.u], function(err, result) {
... done(); ...
});
});
});
You can communicate with more than one database at a time too
You need ssl first..
var fs = require('fs');
var SSLkey = fs.readFileSync('/local/pem/location/key.pem');
var SSLcert = fs.readFileSync('/local/pem/location/cert.pem');
Now the database code
const mysql = require('mysql');
const forumdb_db = mysql.createConnection({
host: 'localhost',
user: 'dbuser',
password: 'dbpassword',
database: 'dbname',
key: SSLkey,
cert: SSLcert,
connectionLimit: 15,
queueLimit: 30,
acquireTimeout: 1000
});
const inventory_db = mysql.createConnection({
host: 'localhost',
user: 'dbuser',
password: 'dbpassword',
database: 'dbname',
key: SSLkey,
cert: SSLcert,
connectionLimit: 15,
queueLimit: 30,
acquireTimeout: 1000
});
Connecting to databases
inventory_db.connect((err0) => {
inventory_db.query("SELECT `bubblebum` FROM `user_inventory` WHERE `index`='1' LIMIT 1;", function(err0, result0, field0) {
console.log(result0[0].bubblebum);
});
});
forum_db.connect((err0) => {
forum_db.query("SELECT `stars` FROM `user_inventory` WHERE `stars`>'100' LIMIT 1;", function(err1, result1, field1) {
console.log(result1[0].stars);
});
});
There is one problem with this, You'll be disconnected after a while of inactivity so you should set up an interval to send a quick request every ten seconds to the sql server.
Related
I'm trying to get data in JSON format. I just copied an old project and changed it IP address to database, username, port, password and database name.
When I try to access data through this addres: localhost:3000/&id=13
The browser just doesn't load them.
When I enter the address with the port without / I see the message with error:
return res.status(500).json({ error: "Грешна заявка. Опитай отново !"})
The same code is pinned to another database and I see the data in JSON format.
I checked 10 times if the username, password, port and database name are correct and they are fine.
The code:
// Create express app
var express = require("express")
var app = express()
var mysql = require('mysql')
var express = require("express")
var cors = require('cors')
app.use(cors())
// Server port
var HTTP_PORT = 3000
var pool = mysql.createPool({
connectionLimit: 10,
host: '192.168.0.1',
user: 'user',
port: '3388',
password: 'password',
database: 'databasename'
});
var ardaforecast = '';
app.route('/')
.get(function (req, res) {
// omitted
res.setHeader('Access-Control-Allow-Origin', '*', 'Cache-Control', 'private, no-cache, no-store, must-revalidate');
//const date = req.query.date;
const id = req.query.id;
pool.query(`CALL Get_Alert_levels_Station(${id})`, function (error, result) {
if (error)
return res.status(500).json({ error: "Грешна заявка. Опитай отново !"})
aladinModel = result;
res.json({ ardaforecast })
});
});
// Start server
app.listen(HTTP_PORT, () => {
console.log("Server running on port %PORT%".replace("%PORT%", HTTP_PORT))
});
pool.on('error', function (err) {
console.log(err.code); // 'ER_BAD_DB_ERROR'
});
app.use(function (req, res) {
res.status(404);
})
;
Can I get an example of how I can fix this or how to find out where the problem is ?
You can use this one to see how what your url contains: https://www.freeformatter.com/url-parser-query-string-splitter.html
In your example, the problem is that you're using & (ampersand), but what it does is separating multiple query parameters. Since you have just one, your url is not properly structured and does not contain any parameters whatsoever.
You should use ? (question mark) to denote the first one:
localhost:3000/?id=13
p.s. Успех ;)
I need to create a simple solution to receive input from an user, query our database and return the result in any way, but the queries can take as long as half an hour to run (and our cloud is configured to timeout after 2 minutes, I'm not allowed to change that).
I made the following solution that works locally, and want to include code to send the query's result via email to the user (in a fire and forget manner), but am unsure as how to do that while returning HTTP 200 to the user.
index.js:
const express = require('express')
const bodyParser = require('body-parser')
const db = require('./queries')
const app = express()
const port = 3000
app.use(bodyParser.json())
app.use(
bodyParser.urlencoded({
extended: true,
})
)
app.get('/', (request, response) => {
response.json({ info: 'Node.js, Express, and Postgres API' })
})
app.post('/report', db.getReport)
app.get('/test', db.getTest)
app.listen(port, () => {
console.log(`App running on port ${port}.`)
})
queries.js:
const Pool = require('pg').Pool
const pool = new Pool({
user: 'xxx',
host: 'xx.xxx.xx.xxx',
database: 'xxxxxxxx',
password: 'xxxxxxxx',
port: xxxx,
})
const getReport = (request, response) => {
const { business_group_id, initial_date, final_date } = request.body
pool.query(` SELECT GIANT QUERY`, [business_group_id, initial_date, final_date], (error, results) => {
if (error) {
throw error
}
response.status(200).json(results.rows)
})
// I want to change that to something like:
// FireNForgetWorker(params)
// response.status(200)
}
module.exports = {
getReport
}
Through the use of callbacks, and based on the design of express, you can send a response and continue to perform actions in that same function. You can, therefore, restructure it to look something like this:
const Pool = require('pg').Pool
const pool = new Pool({
user: 'xxx',
host: 'xx.xxx.xx.xxx',
database: 'xxxxxxxx',
password: 'xxxxxxxx',
port: xxxx,
})
const getReport = (request, response) => {
const { business_group_id, initial_date, final_date } = request.body
pool.query(` SELECT GIANT QUERY`, [business_group_id, initial_date, final_date], (error, results) => {
if (error) {
// TODO: Do something to handle error, or send an email that the query was unsucessfull
throw error
}
// Send the email here.
})
response.status(200).json({message: 'Process Began'});
}
module.exports = {
getReport
}
=============================================================================
Another approach could be to implement a queuing system that would push these requests to a queue, and have another process listening and sending the emails. That would be a bit more complicated though.
I have this basic nodejs script:
var express = require('express'),
Sequelize = require('sequelize'),
promise = require('bluebird'),
app = express(),
optimus = new Sequelize('optimus', 'root', 'test', {host: '127.0.0.1', dialect: 'mysql'}),
query = 'SELECT id FROM borrowers LIMIT 0,10',
query2 = 'SELECT COUNT(*) FROM borrowers';
app.get('/', function(req,res) {
var chain = new Sequelize.Utils.QueryChainer();
console.log('begin');
chain.add(optimus, 'query', [query,null,null,[]])
.add(optimus, 'query', [query2,null,null,[]])
.run()
.success(function() {
console.log('done');
}).error(function(err) {
console.log('oh no');
});
console.log('end');
res.send('Hi Ma!');
});
var server = app.listen(3000, function() {
console.log('Listening on port %d', server.address().port);
}
);
Neither 'done' nor 'oh no' ever fires which leads me to believe that I can' chain raw queries in this manner.
What I'd really like to accomplish is to asynchronously resolve both queries and pass the results back via res.send().
I have to admit to being a complete n00b at nodejs so any insights into how to correctly structure this would be greatly appreciated.
The major issue with your code is the fact, that you are sending a response to the client/browser too early. Instead of res.send-ing at the end of the app.get method, you need to send the answer inside the success respectively inside the error callback. Here you are:
var express = require('express'),
Sequelize = require('sequelize'),
promise = require('bluebird'),
app = express(),
optimus = new Sequelize('sequelize_test', 'root', null, {host: '127.0.0.1', dialect: 'mysql'}),
query = 'SELECT id FROM borrowers LIMIT 0,10',
query2 = 'SELECT COUNT(*) as count FROM borrowers';
app.get('/', function(req,res) {
var chain = new Sequelize.Utils.QueryChainer();
console.log('begin');
chain
.add(optimus.query(query, null, { raw: true }))
.add(optimus.query(query2, null, { raw: true, plain: true }))
.run()
.success(function(results) {
res.send({
resultOfQuery1: results[0],
resultOfQuery2: results[1]
});
}).error(function(err) {
console.log('oh no', err);
});
});
var server = app.listen(3000, function() {
console.log('Listening on port %d', server.address().port);
}
);
Please notice, that I changed the credentials to my local ones. Furthermore also check the arguments of chain.add. Instead of passing the values for an upcoming serial executation, we just throw the actual asynchronous methods into it and let the querychainer handle their promises.
I'm completely new to nodejs + expressjs comming from php and I'm getting trouble how to export/include a var to my routes/users.js file.
on app.js I have:
//database connection
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'dbNodeExpress'
});
... some code
var user = require('./routes/user'); //here I include my routes/files (I dont know if it's right to include the routes here - for learning purposes it works for now)
... more code until starts the server
On my /routes/user.js
app = require('../app');
//var mysql = require('mysql');
var baseUrl = app.get('baseUrl');
app.get('/users_mysql', function(req, res){
connection.query('SELECT * FROM users', function(err, users){
res.json(users);
});
});
and I get the express error: 500 ReferenceError: connection is not defined
The connection works because if I move the content from users.js to app.js I can query the database.
My questions is how to inject the var connection to be used on routes/users.js
Any help / hint to understand this is very appreciated. Thanks in advance.
There are several ways you could do this. A couple solutions might be:
Create a resources.js file that creates and exports the connection. Then require() resources.js in every source file where you need it.
Pass the connection to your user route file. Something like this:
// app.js
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'dbNodeExpress'
});
require('./routes/user')(connection);
// routes/user.js
module.exports = function(connection) {
app.get('/users_mysql', function(req, res){
connection.query('SELECT * FROM users', function(err, users){
res.json(users);
});
});
};
create a database connector javascript file. as like database_connector.js
and require it when ever you want to have the connection pooled or the connection class availabel to your models. tip : you can also export config files like below or use barely values.
var mysql = require('mysql');
var config = require("./config");
function Connection() {
this.pool = null;
this.init = function() {
this.pool = mysql.createPool({
connectionLimit: config.poolSize,
host: config.host,
user: config.user,
password: config.password,
database: config.database,
debug:config.debug,
});
};
this.acquire = function(callback) {
this.pool.getConnection(function(err, connection) {
callback(err, connection);
});
};
console.log("connection"+this.pool);
}
module.exports = new Connection();
I want to know how ExpressJS works in the server side
I need some information on Server side, Main things are,As per my knowledge,
ExpressJS can perform all the functionalists of a PHP - - - IS it
true ?
My Client(Android) is ready to submit a POST request to Server
If i can send one single information in the form of (Key,value) pair,
can the Express accept that pair- - Identify the value based on key
and, to perform a sql query to Database based on the value received
from android client?
If it can how it does it?
MY Express Program ( It gives a Response without scenario explained above - How to modify this program )
var express = require('express')
, async = require('async')
, http = require('http')
, mysql = require('mysql');
var app = express();
var connection = mysql.createConnection({
host: 'localhost',
user: '*********',
password: "*****",
database: 'DB'
});
connection.connect();
// all environments
app.set('port', process.env.PORT || 7002);
//
//REQUEST FOR FIRST REQUEST
//
app.get('/',function(request,response){
var name_of_restaurants, RestaurantTimings;
async.series( [
// Get the first table contents
function ( callback ) {
connection.query('SELECT * FROM restaurants', function(err, rows, fields)
{
console.log('Connection result error '+err);
name_of_restaurants = rows;
callback();
});
},
// Get the second table contents
function ( callback ) {
connection.query('SELECT * FROM RestaurantTimings', function(err, rows, fields)
{
console.log('Connection result error '+err);
RestaurantTimings = rows;
callback();
});
}
// Send the response
], function ( error, results ) {
response.json({
'restaurants' : name_of_restaurants,
'RestaurantTimings' : RestaurantTimings
});
} );
} );
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
Hope I am clear
Thanks ,
You can send information via query params or as part of the url path. If you send it as a query param, you can access it using
req.query.keyName;
If you want to send the value as part of the url, you'll have to add a route to accept it. You can accept variable content in a url by using the :keyName form. Express will capture it in req.params. So it would look a little like this:
app.get('/some/url/:keyName', function(req, res, next){
var keyName = req.params.keyName;
// . . .
});
Then you can send your http request to '/some/url/someKeyValue' and the variable keyName will then be equal to whatever you add after /some/url/.
If you're POSTing data in the body of the request, access it with req.body.keyName.
EDIT: Here's an attempt at using the original code. Note that I'm still making up values and guessing at what the intent is.
var express = require('express')
, async = require('async')
, http = require('http')
, mysql = require('mysql');
var app = express();
var connection = mysql.createConnection({
host: 'localhost',
user: '*********',
password: "*****",
database: 'DB'
});
connection.connect();
// all environments
app.set('port', process.env.PORT || 7002);
//
//REQUEST FOR FIRST REQUEST
//
app.get('/',function(request,response){
var name_of_restaurants, RestaurantTimings;
async.series( [
// Get the first table contents
function ( callback ) {
connection.query('SELECT * FROM restaurants WHERE name = ' . request.body.name, function(err, rows, fields) {
console.log('Connection result error '+err);
name_of_restaurants = rows;
callback();
});
},
// Get the second table contents
function ( callback ) {
connection.query('SELECT * FROM RestaurantTimings', function(err, rows, fields) {
console.log('Connection result error '+err);
RestaurantTimings = rows;
callback();
});
}
// Send the response
], function ( error, results ) {
response.json({
'restaurants' : name_of_restaurants,
'RestaurantTimings' : RestaurantTimings
});
} );
} );
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
But you should really not query directly like that because of SQL injection. I've never used MySQL from node, but I'm sure there is some way to use parameterized queries. Hope this is more helpful.
Also, I'm assuming that the data will be passed in the request body, since you said you are ready to POST to the server.