I have this code:
app.post('/api/command', function (req, res, next) {
var clientCommand = req.body.command;
console.log("ClientCommand: ", clientCommand);
if (!req.session.step || req.session.step === EMAIL) {
// find user in db with email
users.findOne({email: clientCommand}, function (err, result) {
if (err) {
return console.log("error: ", err);
}
console.log("result: ", result.email);
// if user exists add user in session
if (result != null) {
req.session.user = result;
}
});//.catch(console.log);
console.log("session outside: ", req.session.user);
// change step to password
req.session.step = PASSWORD;
}
The problem is I want to access req.session.user outside users.findOne(...). But the output is:
ClientCommand: example#gmail.com
session outside: undefined
Any help will be appreciated.
P.S. Also, I would like to know how express-session works and how it stores data in cookies (or on server-side).
Findone is a async command due to which you are getting undefined.
Even if you will notice
"session outside:" is coming first
only after that "result: " console will come.
So if you have to move code inside findone or use custom middleware where you can execute query.
use this type of code in app js before calling routes
app.use(function(req,res,next){
users.findOne({email: clientCommand}, function (err, result) {
if (err) {
return console.log("error: ", err);
}
console.log("result: ", result.email);
// if user exists add user in session
if (result != null) {
req.session.user = result;
next(); // After setting user , route will call
}else{
next(); // will allow to go to route even if no user found
}
});//.catch(console.log);
})
if you want to call it at particular url then use
app.use("[your url]",function(req,res,next){
Related
Node js/Javascript doesn't catch the error while querying mysql server
The nodejs server queries the submittedName from form, checks the database along with submittedName. If submittedName matches with the submittedName, renders success. If it doesn't match, it should render notfound.
But indeed, it does not. Instead, it renders success. Even on wrong input.
app.post("/whatisyourname", (req, res) => {
var submittedName = req.body.details;
console.log(details);
//query the mysql database
conn.query(
"SELECT * FROM giftapp where name= ?",
submittedName,
(err, rs) => {
//handle the error
if (err) {
console.log(err);
//while it should render the "notfound" file,
//it renders "success"
res.render("notfound");
} else {
//if no error, render success
res.render("success", { myR: rs[0] });
}
}
);
I expect to be forwarded to "notfound" in case of wrong input or just any error
And to be forwarded to "success" in case of correct input
The express server or sql connection or callback won't throw any error in this case. You will get an error if something goes wrong while querying the db, i.e Invalid query or connection error etc. In your case the query executes successfully and gives you the result which is an empty array. You need to manually check and return the result. Change your code like:
app.post("/whatisyourname", (req, res) => {
const submittedName = req.body.details;
console.log(details);
//query the mysql database
conn.query(
"SELECT * FROM giftapp where name= ?",
submittedName,
(err, results) => {
if (err) {
console.log(err);
res.render("notfound");
} else {
if (results && results.length > 0) {
res.render("success", { myR: results[0] });
} else {
res.render("notfound");
}
}
});
});
Hope this helps :)
var submittedName = req.body.details;
var sql = 'SELECT * FROM giftapp WHERE name = ?';
con.query(sql, [submittedName], function (err, result) {
if (err) res.render("notfound"); // if you view is called notfound.ejs remove the space between not and found.
console.log(result);
res.render("success", { myR: result[0] }); // need success.ejs
});
My res.json in my first block of code works, but in the else part of my if statement, it does not. The block that doesnt work, checks for a record in a database then im trying to return the response but im not receiving it.
I've checked and the response is a string, I thought it would have worked as the top part of the code successfully returns the string and it shows in dialogflow (where im trying to return it)
The response is successfully consoled right before the res.json but I do not receive it from the source of the request.
code:
app.post('/webhook/orderinfo', (req, res) => {
const intent = req.body.queryResult.intent.displayName;
const domain = "chatbotdemo.myshopify.com";
const order = req.body.queryResult.parameters["number-sequence"];
if (intent.includes('Order Number')) {
url = "https://test-hchat.com/api/orders/" + domain + "/" + order;
request(url)
.then(function (response) {
order_res = JSON.parse(response)
order_res["fullfillmentText"] = "Hi, Please find your order details below:";
res.json({
"fulfillmentText": JSON.stringify(order_res)
})
})
.catch(function (err) {
console.log(err)
});
// THIS PART DOESNT RETURN THE RESPONSE.
} else {
const domain = 'testStore'
db.getClientsDialog(domain, intent, (response) => {
const fullResponse = response.response
res.json({
fullResponse
})
})
}
});
The database code:
getClientsDialog: function (domain, intent, callback) {
MongoClient.connect('mongodb://efwefewf#wefwef.mlab.com:15799/wefwef', function (err, client) {
if (err) throw err;
var db = client.db('asdsad');
db.collection('dialog').findOne({ domain: domain, intent: intent }, function (err, doc) {
if (!err) {
callback(doc)
} else {
throw err;
callback(err)
}
client.close();
});
console.dir("Called findOne");
});
}
Could it be because this second use of the res.json in the else statement, is trying to call the db first and therefore the link is lost to send the data back?
I am still a beginner in the Firebase world and I have been trying to figure out what the problem is with the below code but I failed in all possible ways.
The code is supposed to retrieve the uid from the user profile in the database, then use it to update the authentication profile, then again to update the database profile if the authentication profile update was successful.
In index.js I have defined an exported function to deal with POSTed params from HTML forms. The code below defines the handler function in another module file:
exports.auUpdateUserByEmail = (req, res) => {
// This handler function will retrieve the POSTed params of user profile
// and will attempt to update the existing user authentication as well as
// the database profiles.
//
// This function accepts the following params:
// 1. User email // 2. Phone number // 3. password // 4. Display name
// 5. Photo url // 6. Disabled Flag
//
var db = admin.firestore();
var uEmail = req.body.userEmail;
var dName = req.body.displayName;
var userId = "";
var newuser = {
displayName: dName
}
console.log("Email passed: " + uEmail);
// Fetch the user UID by user email...
res.write('User UID: ' + userId);
console.log('User UID: ' + userId);
// attempt to update the user authentication profile...
return db.collection('Users').where('email', '==', email).get()
.then(snapshot => {
snapshot.forEach(doc => {
var d = doc.data();
console.log("doc.id: " + doc.id + " - d.email: " + d.email);
if(d.email == email)
{
userId = d.uid;
}
});
return admin.auth().updateUser(userId, newuser);
}).then(function(userRecord) {
// The updating was successful... Attempt to update User Details in
// database User Profile...
console.log("User Updated Successfully. UID: " + userRecord.uid);
retUid = userRecord.uid;
// Create a reference to the Users Database...
var docRef = db.collection('Users');
// Update the user profile document.
return docRef.doc(userRecord.uid).update(newuser);
}).then(result => {
// everything went fine... return User UID as a successful result...
res.write(userId);
return res.end();
}).catch(function(error) {
console.log("doc.update - Error updating user profile in database:", error);
return res.end();
});
}
In index.js, I have the following exports definition:
var appAuth = express();
//Here we are configuring express to use body-parser as middle-ware.
appAuth.use(bodyParser.urlencoded({ extended: false }));
appAuth.use(bodyParser.json());
appAuth.post('/updateUserByEmail', authusers.auUpdateUserByEmail);
exports.usersAuthFunctions = functions.https.onRequest(appAuth);
I have to say that I got it to work fine to get the uid, update the auth profile, and then update database profile, but it keeps on waiting for the function return.
Appreciate your valuable help. Thanks.
I have updated the code as below and it does the jobs but returns a blank page as the HTTPS exits before the promises are complete which fires "Error: write after end" error.
var fetch_uid = db.collection('Users').where('email', '==', uEmail).get()
.then(snapshot => {
// var userId = snapshot.data.uid;
snapshot.forEach(doc => {
var d = doc.data();
console.log("doc.id: " + doc.id + " - d.email: " + d.email);
if(d.email == uEmail)
{
userId = d.uid;
res.write('User UID: ' + userId);
console.log('User UID: ' + userId);
}
});
return admin.auth().updateUser(userId, newuser);
}).then(function(userRecord) {
// The updating was successful... Attempt to update User Details in
// database User Profile...
console.log("User Updated Successfully. UID: " + userRecord.uid);
retUid = userRecord.uid;
// Create a reference to the Users Database...
var docRef = db.collection('Users');
// Update the user profile document.
return docRef.doc(userRecord.uid).update(newuser);
}).then(result => {
// everything went fine... return User UID as a successful result...
res.write(userId);
return;
}).catch(function(error) {
console.log("doc.update - Error updating user profile in database:", error);
return;
});
res.end();
A previous answer of mine on Cloud Functions for Firebase HTTP timeout might be of help here:
Cloud Functions triggered by HTTP requests need to be terminated by
ending them with a send(), redirect(), or end(), otherwise they
will continue running and reach the timeout.
From your code examples, it looks like your then(){} promise returns are ending with res.end(), but the entire function is returning the Promise from:
return db.collection('Users').where('email', '==', email).get()
Which could be stopping it from ending when you want it to. With HTTPS triggers, you don't need to return a Promise to keep the function running, only a result.
Try removing the return statement from this line:
db.collection('Users').where('email', '==', email).get()
Then you just need to ensure that all exit routes (or termination points) end with res.end() or similar, so currently you have 2 termination points:
}).then(result => {
// everything went fine... return User UID as a successful result...
res.write(userId);
res.status(200).end();
}).catch(function(error) {
console.log("doc.update - Error updating user profile in database:", error);
res.status(500).end();
});
Hello you beautiful people you.
I'm trying to create REST APIs using node.js connected to an OracleDB, but i'm pulling my hair out trying to get these stupid bind variables working.
Here's my code:
app.get('/mailsummary/:SCHEMA', function (req, res) {
"use strict";
oracledb.getConnection(connAttrs, function (err, connection) {
if (err) {
// Error connecting to DB
res.set('Content-Type', 'application/json');
res.status(500).send(JSON.stringify({
status: 500,
message: "Error connecting to DB",
detailed_message: err.message
}));
return;
}
connection.execute("select * from :SCHEMA.event#db3", [req.params.SCHEMA], {
outFormat: oracledb.OBJECT // Return the result as Object
}, function (err, result) {
if (err || result.rows.length < 1) {
res.set('Content-Type', 'application/json');
var status = err ? 500 : 404;
res.status(status).send(JSON.stringify({
status: status,
message: err ? "Error getting vendor mailing summary." : "Vendor or DB does nto exist.",
detailed_message: err ? err.message : ""
}));
} else {
res.contentType('application/json').status(200).send(JSON.stringify(result.rows));
}
// Release the connection
connection.release(
function (err) {
if (err) {
console.error(err.message);
} else {
console.log("GET /mailsummary/" + req.params.SCHEMA + " : Connection released");
}
});
});
});
});
For some reason i'm getting the error
OracleDB : ORA-01036: illegal variable name/number
If I remove the bind variable, assign a static value and remove "req.params.SCHEMA" after the sql statement and leave the brackets blank, it works.
connection.execute("select * from peeps.event#db3", [], {
outFormat: oracledb.OBJECT // Return the result as Object
I know it's got to be something simple with the way i'm pulling in the bind variable, but i'm pulling my hair out.
Please help me Obi-Wan Kenobi... you're my only hope.
Thanks!
Bind variables are placeholders used to transfer data between database and client program. You are trying to transfer the text of the SQL statement - your usage won't work.
This bind behavior is not specific to node-oracledb; it's the way Oracle works. It helps keep data and statement text separate.
There is some general bind info at: http://docs.oracle.com/database/122/LNOCI/binding-and-defining-in-oci.htm#GUID-77A26CEA-1C41-46A2-866C-622F9FEB5482
I am making a chat application which requires users to log in, I have so far managed to get the login system working by using UserApp.io, but I cant seem to find a way which would send a "Callback" back to the user who has emited the information to the server.
So for index.html, when a login form is submitted, it would gather the values of the two fields and emit the data to the backend.
$('form#login').submit(function() {
var data = {};
data.email = $("#login_email").val();
data.password = $("#login_password").val();
socket.emit('user login', data);
});
In the index.js file, it receives the details and checks using the UserApp API that the user is valid and all the details are correct. It also retrieves information like the first and last name.
socket.on('user login', function (user) {
logger.info('Receiving login info for "' + user.email + '"...');
UserApp.User.login({"login": user.email, "password": user.password}, function (error, result) {
if (error) {
logger.error('Login failed: ' + error.message);
} else {
var userToken = result.token;
var userID = result.user_id;
console.log("User has logged in.");
UserApp.User.get({
"user_id": userID
}, function (error, result) {
if (error) {
logger.error(error.message);
} else {
logger.info(result[0]['first_name'] + " " + result[0]['last_name'] + " Has logged in!")
}
});
}
});
});
So here is my issue. I cant seem to find a way of giving a callback to index.html so it can show errors like "Incorrect username".
So is there a way of giving a callback to one person, more specificly, the person who submitted the login form?
Any help would be appreciated.
Thanks.
socket.io has acknowledgement callbacks, here are the docs
http://socket.io/docs/#sending-and-getting-data-(acknowledgements)
Add a callback function as the third argument when emitting
$('form#login').submit(function() {
var data = {};
data.email = $("#login_email").val();
data.password = $("#login_password").val();
socket.emit('user login', data, function (result) {
console.log(result);
});
});
and then the callback function server side can have an additional parameter which is the callback you defined when emitting
socket.on('user login', function (user, callback) {
logger.info('Receiving login info for "' + user.email + '"...');
UserApp.User.login({"login": user.email, "password": user.password}, function (error, result) {
if (error) {
logger.error('Login failed: ' + error.message);
} else {
var userToken = result.token;
var userID = result.user_id;
console.log("User has logged in.");
UserApp.User.get({
"user_id": userID
}, function (error, result) {
if (error) {
logger.error(error.message);
} else {
logger.info(result[0]['first_name'] + " " + result[0]['last_name'] + " Has logged in!")
return callback('your results');
}
});
}
});
});