I'm writing a Node.js application using Express and a PostgreSQL database using node-postgres. I want to look up the current user's username and real name based on their email, and set them in req.session. However, if I set them where I am in the code below, they are undefined when we leave that block (i.e. the first console.log statements print the correct info, the second set prints undefined. How can I solve this?
var client = new pg.Client(app.conString);
var realname = "";
var username = "";
client.connect();
var query = client.query(
"SELECT * FROM users WHERE email = $1;",
[req.session.email]
);
query.on('row', function(row) {
req.session.realname = row.realname;
req.session.username = row.username;
console.log(req.session.realname);
console.log(req.session.username);
});
console.log(req.session.realname);
console.log(req.session.username);
query.on('end', function() {
client.end();
});
The second pair of console.log will execute before the query-results are available (in the row event handler).
If your code is going to be used in an Express route, you would use something like this:
app.get('/', function(req, res) {
var client = new pg.Client(app.conString);
var realname = "";
var username = "";
client.connect();
var query = client.query(
"SELECT * FROM users WHERE email = $1;",
[req.session.email]
);
query.on('row', function(row) {
req.session.realname = row.realname;
req.session.username = row.username;
});
query.on('end', function() {
client.end();
res.send(...); // <-- end the request by sending back a response
});
});
An alternative for using the EventEmitter interface for node-postgres would be to just pass a callback to query (which looks better with Express IMHO):
client.query(
"SELECT * FROM users WHERE email = $1;",
[req.session.email],
function(err, results) {
if (err)
// handle error
else
if (results.length)
{
req.session.realname = results[0].realname;
req.session.username = results[0].username;
}
res.send(...); // done
});
Related
I want to fetch some values from the current user Session and use them in MySQL query. I am working on Node.js and using redis to manage sessions.
File Name:User.js
var sessionUtils = require('./../services/sessionUtils');
var Constants = require('./../constants');
var config = require('./../config');
var databaseUtils = require('./../services/databaseUtils');
var redisUtils = require('./../services/redisUtils');
var util = require('util');
showUserPage: function* (next){
var queryString = "";
var query = "";
/*Do something to store session in variable*/
queryString = "select * from table where state='%s' and city='%s';";
query = util.format(queryString,/*state variable here*/, /*city variable
here*/);
var user = yield databaseUtils.executeQuery(query);
console.log(query);
yield this.render('user', {
user:user
});
}
File Name: sessionUtils.js
var redisUtils = require('./redisUtils');
var uuid = require('uuid');
var thunkify = require('thunkify');
saveUserInSession: function(user, cookies) {
var sessionId = uuid.v1(); // uuid: uniqe id every time
var sessionObj = {user: user};
redisUtils.setItemWithExpiry(sessionId, JSON.stringify(sessionObj), 86400); // 86400: for 1 day
cookies.set("SESSION_ID", sessionId);
},
getCurrentUser: thunkify(function(sessionId, callback) {
var currentUser;
if(sessionId) {
redisUtils.getItemWithCallback(sessionId, function(err, res) {
if(err) {
logger.logError(err);
}
if(res == null) {
callback(currentUser);
} else {
callback(err, JSON.parse(res).user);
}
});
} else {
callback(currentUser);
}
})
I am using line below in Login.js file to save user in session .
sessionUtils.saveUserInSession(results[0], this.cookies);
Help me out with this.
I have solved this problem by placing following code in place of /* Do something to store session in variable */
var sessionId = this.cookies.get("SESSION_ID");
var currentUser = yield sessionUtils.getCurrentUser(sessionId);
and used it in MySQL query as given below:
queryString = "select * from table where state='%s' and city='%s';";
query = util.format(queryString,currentUser.state, currentUser.city);
Hope, it helps others too.
In the following code, data are retrieved from a database into JSON. What I would like to do is to display each single data as a plain text:
var http = require("http");
var mysql = require('mysql');
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false })
app.use(express.static('public'));
app.get('/Search.html', function (req, res) {
res.sendFile( __dirname + "/" + "Search.html" );
})
var connection = mysql.createConnection(
{
host : 'localhost',
user : 'root',
password : 'passpass',
database : 'SocialQuery',
}
);
connection.connect();
app.post('/process_post', urlencodedParser, function (req, res) {
// Prepare output in JSON format
response = {
SearchType:req.body.SearchTypes,
Term:req.body.term
};
//var vas = JSON.stringify(response);
var search = req.body.SearchTypes;
var term = req.body.term;
var queryString;
if(search == 'Author')
{
queryString = 'Select Label,TDate from Tweet where AuthorID IN (select ID from Author where Lable = ?)';
}
else if(search == 'Mention')
{
queryString = 'select Tweet.Label, Tweet.TDate, Author.Lable from Tweet, Author where Tweet.ID IN (select TweetID from TweetMention where MentionID IN (select ID from Mention where Label = ?)) AND Author.ID = Tweet.AuthorID'
}
var query = connection.query(queryString, [term], function(err, rows) {
console.log(rows);
var tweet = JSON.stringify(rows);
res.write("Author: " + tweet.Lable);
res.write("Date: " + tweet.TDate);
res.end();
});
console.log(query.sql);
})
//}).listen(8081);
http.createServer(app).listen(8081);
console.log('Server running at http://127.0.0.1:8081/');
When I print the data using res.write(JSON.stringify(rows)); I got the following:
[{"Label":"lest play hero","TDate":"2016-03-12T00:00:00.000Z","Lable":"esti_jony"},{"Label":"u r the best ! Ill always keep","TDate":"2016-03-08T00:00:00.000Z","Lable":"adam03cooper03"}]
but when I run the code above, I got:
Author: undefined Date: undefined
What I understood is the problem because two rows of data have been retrieved and I do not know how to let it display each author (Lable) and each date (TDate).
You're converting a javascript object to a JSON string and then trying to access the javascript object's properties on the string. That won't work. You want to use the javascript object instead, but since there is more than one row, you will have to either choose which one you want to respond with or write all rows or whatever your use case calls for.
For example:
var query = connection.query(queryString, [term], function(err, rows) {
if (err) throw err;
for (var i = 0; i < rows.length; ++i) {
var tweet = rows[i];
res.write("\nAuthor: " + tweet.Lable);
res.write("\nDate: " + tweet.TDate);
if (i + 1 < rows.length)
res.write('\n');
}
res.end();
});
I have a server with 3 databases with identical tables.
DB1, DB2 and DB3.
When I work with a database I use:
app.js
var cnxDB= require('./routes/cnxDB');
app.post('/userSave', cnxDB.userSave);
cnxDB.js:
var sql = require('mssql');
var qs = require('querystring');
var colors = require('colors');
var config = {user: 'user',password: 'pass',server: '127.0.0.1',database: nameDB',
options: {
encrypt: false
}
};
sql.connect(config, function(err) {
//Connection
});
exports.userSave = function(req, res) {
//response
};
When initializing the application immediately makes the connection to the database.
I need to know how you can do to choose the database.
app.post('/selectBD', function(req, res){
var body = req.body; // accede a la informaciĆ³n enviada por el socket
console.log(body);
if(body.cnx == 1)
{
var cnx = require('./routes/bdUno');
app.get('/yuri', cnx.findall);
}
if(body.cnx == 2)
{
var cnx = require('./routes/bdDos');
app.get('/yuri', cnx.findall);
}
if(body.cnx == 3)
{
var cnx = require('./routes/bdTres');
app.get('/yuri', cnx.findall);
}
res.status(200).json("Ok");
});
Thank you.
In cnxDB.js set up 3 connections:
var connections = {
<dbname>: null,
<dbname>: null,
<dbname>: null
}
go to mssql and look at "Quick Example". It creates a connection and saves it in a variable. You'd want to do that 3 times for each db and save them in connections under the corresponding db name.
Then the functions you export from cnxDB.js should have a way to know which db you want them to use. By the looks of it you want to have some indication of what db needs to be used in the body of that request. You can use that to pick the db.
When I use jQuery ajax to retrieve data from nodejs (with express4), nodejs sends empty response back before data loaded from mongodb.
This is the message from nodejs console:
GET /query?uid=1 - - ms - -
And this is the error message from Chrome console:
GET http://192.168.1.105:3000/query?uid=1 net::ERR_EMPTY_RESPONSE
I can confirm that data are correctly loaded from mongodb because data can be printed on nodejs console after nodejs sent the empty response. And this is exactly the problem. Why nodejs sends reponse to client before data have been prepared?
I know nodejs is asynchronous and I pay much attention to this great feature, but I still have this problem.
This is my client code:
$.getJSON('/query', {uid:1}, function(response) { console.log('finished!'); });
And this is my server code:
var express = require('express');
var mongodb = require('mongodb');
var GeoJSON = require('geojson');
var strftime = require('strftime');
var router = express.Router();
var MongoClient = mongodb.MongoClient;
router.get('/query', function(req, res, next) {
var url = "mongodb://localhost/example_db";
var collection_name = "example_collection";
var poi = req.query.poi ? req.query.poi.split("||") : null;
var time = req.query.time;
var uid = req.query.uid;
var condition = {};
if (poi) condition.poiname = {$in: poi};
if (time) condition.checkin_time = {$gte:new Date(time.start_time), $lte:new Date(time.end_time)};
if (uid) condition.uid = parseInt(uid);
MongoClient.connect(url, function(err, db) {
if (err) console.log('connection error');
var collection = db.collection(collection_name);
collection.find(condition).sort({checkin_time:1}).toArray(function(err, result) {
if (err) {
console.log(err);
return res.send('error!');
}
if (!result) return res.send('no data');
//This line prints the result after empty response has been sent.
console.log(result);
var data = {};
data['geojson'] = GeoJSON.parse(result, {Point:'loc', include:['poiname', 'uid', 'checkin_time']});
res.json(data);
db.close();
});
});
My data are a little bit large, 12G stored in mongodb. So it usually takes about 3 minutes or more to complete the query. When I use findOne to retrieve only a single document, this is no problem.
Does the data size cause the problem?
Try GeoJSON.parse with callback
var data = {};
GeoJSON.parse(result, {Point:'loc', include:['poiname', 'uid', 'checkin_time']}, function (geojson) {
data['geojson'] = geojson;
res.json(data);
db.close();
});
I have written an API that queries a MySQL database and outputs the corresponding results visiting an url. This is the code:
//server.js
var express = require('express'),
mysql = require('mysql'),
app = express(),
connectionpool = mysql.createPool({
host : 'localhost',
user : 'root',
password : 'password',
database : 'database'
});
app.get('/:transcript', function(req,res){
var var1 = req.param('transcript');
exports.var1 = var1;
var queries = require('./queries'),
query1 = queries.query1;
//Connection to MySQL
connectionpool.getConnection(function(err, connection) {
if (err) {res.send({result: 'error connection'})}
connection.query(query1, function(err, rows) {
if (err) {res.send({result: 'error query1'})};
counter = 0; root = {};
rows.forEach(function (row) {
build_actor(row.Transcript_alias, function(exprobject1) {
counter += 1;
//Defining and filling objects
main = {};
main.Official_transcript_name = row.Transcript_name;
main.Expression = exprobject1;
root[row.Transcript_alias] = main;
if (counter == rows.length) {
res.write(JSON.stringify(root, null, '\t'));
res.end();
}
});
});
connection.release();
});
//CallBack
function build_actor(transcript, callback) {
//Other, secondary queries:
var query2 = 'SELECT * FROM expression WHERE transcript_alias = "' + transcript + '";',
connection.query(query2, function(err, rows1) {
if (err) {res.send({result: 'error query2'})}
var exprobject2 = {},
exprobject1 = {};
for (i = 0; i < rows1.length; i++) {
Conditions = rows1[i].conditions;
Tissue = rows1[i].tissue;
FPKM = rows1[i].FPKM;
exprobject2[Tissue] = FPKM;
if (Conditions in exprobject1) {
exprobject1[Conditions].push(exprobject2);
} else {
exprobject1[Conditions] = [];
exprobject1[Conditions].push(exprobject2);
}
}
callback(exprobject1);
});
}
});
});
app.listen(3000);
console.log('Listening on port 3000');
This script calls a required file where there are my queries:
//queries.js
var server = require('./server'),
query1 = 'SELECT distinct(transcript_alias)\
FROM transcript_features \
WHERE f.transcript_alias = "' + var1 + '";';
exports.query1 = query1;
I go to the contents of this script this way:
http://localhost:3000/AC149829.2_FGT004
http://localhost:3000/AC148152.3_FGT007
When I first visit http://localhost:3000/AC149829.2_FGT004, the API shows the correct results for the variable AC149829.2_FGT004. However, when changing the variable to AC148152.3_FGT007, it continues showing the information for the variable AC149829.2_FGT004. In order to see the results for AC148152.3_FGT007, I must kill the script, call it again, and visit for the first time http://localhost:3000/AC148152.3_FGT007. In conclusion, results are not refreshed.
How is that? I tried with a simple:
app.get('/:transcript', function(req,res){
var input = req.param('transcript');
res.send(input);
});
but it works well...
EDIT. I found the source of my problem. query1 is always the same. The script only calls once:
exports.var1 = var1;
var queries = require('./queries'),
query1 = queries.query1;
There's a way to overcome this limitation?
I found the solution for my problem. As
//server.js
exports.var1 = var1;
var queries = require('./queries'),
query1 = queries.query1;
is executed once and remains in the cache, I changed my code without exporting var1:
//server.js
var queries = require('./queries'),
query1 = queries.query1 + var1;
and
//queries.js
var server = require('./server'),
query1 = 'SELECT distinct(transcript_alias)\
FROM transcript_features \
WHERE f.transcript_alias = ';
exports.query1 = query1;
In other words, I import my query to server.js without any variable. The variable is assigned at server.js.