Small problem when using POST and adding an INSERT. Works as below, but want to use a callball after the data has been inserted. At the moment the database is being updated. (good) but can't use the callback - I would expect this to be just below the throw error. So you could use result.insertId. Any thoughts welcome?
router.post('/group/:id', function(req, res) {
var idToken = req.params.id;
admin.auth().verifyIdToken(idToken).then(function(decodedToken) {
var userID = decodedToken.uid;
var name = encrypt(req.body.group);
getID(userID, function(result){
var ID = result;
var post = {ID:ID, name:name};
db.query('INSERT INTO cu_groups SET ?', post, function (error, results, fields) {
if (error)throw error;
//*** when I add response here get 502 bad gateway error.
});
res.sendStatus(200);
}); // depends on getID
// admin.auth cat
}).catch(function(error) {
res.sendStatus(error);
});
});
try this way :
router.post('/group/:id', function(req, res) {
var idToken = req.params.id;
admin.auth().verifyIdToken(idToken).then(function(decodedToken) {
var userID = decodedToken.uid;
var name = encrypt(req.body.group);
getID(userID, function(result){
var ID = result;
var post = {ID:ID, name:name};
db.query('INSERT INTO cu_groups SET ?', post, function (error, results, fields) {
if(error){
return res.status(500).send(error);
}
if(!error && results){
return res.status(200).send(results);
}
});
});
}).catch(function(error) {
return res.status(500).send(error);
});
});
if you want to use callback then ,create a separate function like :
var insertData = function(query,data,callback){
db.query(query, data, function (error, results, fields) {
if(error){callback(error,null);}
if(!error && results){callback(null,results);}
});
});
and call this way inside getID :
getID(userID, function(result){
var ID = result;
var post = {ID:ID, name:name};
insertData('INSERT INTO cu_groups SET ?', post, function (error,data){
if(error){
return res.status(500).send(error);
}
if(data){
return res.status(200).send(data);
}
});
});
Working code below many thanks to Saurabh Mistry. I removed the SET post and added the table fields and values explicity.
router.post('/group/:id', function(req, res) {
var idToken = req.params.id;
admin.auth().verifyIdToken(idToken).then(function(decodedToken) {
var userID = decodedToken.uid;
var name = encrypt(req.body.group);
getID(userID, function(result){
var ID = result;
// query
let query = "INSERT INTO cu_groups (ID, name) VALUES('" + ID + "','" + name + "')";
// execute query
db.query(query, (error, result) => {
if(error){
return res.status(500).send(error);
}
if(!error && result ){
return res.send(result);
}
});
}); // depends on getID
// admin.auth cat
}).catch(function(error) {
return res.status(500).send(error);
});
});
Related
I have the following code in NodeJS which works well to;
Begin a MySQL transaction;
Create an audiopost;
Update an audiopost.
Check to see if tag1 exists and if not, create it and insert into a tag table. If it does exist simply insert it to the tag table.
Commit the transaction;
But now I'd like to also check for tag2 and tag3 also.
Unfortunately, I can't figure out where and how to place the commit block
in order to keep it all as a single transaction.
If I put it just before the closing of the check for "tag1" the code won't get as far as "tag2" and "tag3". But if I put it after then the closing brackets to the connection queries are in the wrong place. Here's the code;
var mysql = require("mysql");
var express = require("express");
var connection = require("../database");
var createAudiopost = function(req, res, next){
var title = req.body.title;
var userid = req.body.userid;
var opid = req.body.opid;
var tag1 = req.body.tag1;
var tag2 = req.body.tag2;
var tag3 = req.body.tag3;
connection.beginTransaction(function(err) {
if (err) { throw err; }
connection.query('INSERT INTO ?? (title,userid,opid) VALUES (?, ?, ? )', ['audioposts',title,userid,opid], function(err, result) {
if (err) {
connection.rollback(function() {
throw err;
});
}
var audioname = userid + '-' + result.insertId + '.m4a';
var newid = result.insertId;
console.log("newid: " , newid );
connection.query('UPDATE ?? SET audioname=? WHERE audioid = ?', ['audioposts',audioname,newid], function (error, result, fields) {
if (err) {
connection.rollback(function() {
throw err;
});
}
if (tag1) {
connection.query('SELECT tagid FROM tags WHERE tagname = ?', [tag1], function (error, result, fields) {
if (err) {
connection.rollback(function() {
throw err;
});
}
const tagid1 = result[0].tagid;
if (result < 1) {
connection.query('INSERT INTO tags SET tagname = ?', [tag1], function (error, result, fields) {
if (err) {
connection.rollback(function() {
throw err;
});
}
console.log("lets see this ridiculous result", result);
const tagInsertId = result.insertId;
connection.query("INSERT INTO entitytag SET audioid = ?, tagid = ?, userid = ?", [newid, tagInsertId, userid], function (error, result, fields) {
if (err) {
connection.rollback(function() {
throw err;
});
}
connection.commit(function(err) {
if (err) {
connection.rollback(function() {
throw err;
});
}
console.log('success!');
newid = result.insertId;
res.json({
"title" : title,
"userid" : userid,
"opid" : opid,
"insertid": newid
}); //resjson success
}); //commit
}); // insert entitytags
}); // insert tags
} // if row
else {
connection.query("INSERT INTO entitytag SET audioid = ?, tagid = ?, userid = ?", [newid, tagid1, userid], function (error, result, fields) {
if (err) {
connection.rollback(function() {
throw err;
}); //err
} //err
connection.commit(function(err) {
if (err) {
connection.rollback(function() {
throw err;
});
}
console.log('success!');
res.json({
"title" : title,
"userid" : userid,
"opid" : opid,
"insertid": newid,
"tag1": tag1
}); //resjson success
}); //commit
}) // insert entitytag2
}
}); //select tagid
}//tag1
}); //update
}); //insert
}); //begin transaction
} //createaudiopost
module.exports = createAudiopost;
Any suggestions for how I can complete such a complex transaction? I basically need to repeat the entire section of if (tag1) for tag2 and tag3.
With an HTML5 game I am developing at the moment, I get the player's username and ID through a token sent in by the client which are all stored in a database. Everything was working perfectly up until I had to actually set the values for the player.
I've been searching all over the internet for similar problems that I am facing, and have come up with nothing. I am not sure if this is a variable scope problem or if I am taking the wrong approach to doing this.
Anyways, here's both the socket.player and getUserSession function
var newUserID;
var newUsersName;
socket.player = {
id: newUserID,
x: randomInt(100,400),
y: randomInt(100,400),
username: newUsersName
}
function getUserSession(sessionKey, callback){
var sql = "SELECT * FROM game_sessions WHERE unique_key=? AND still_active=?";
var stillActive = 1;
var returnData = [];
db.query(sql, [sessionKey, stillActive], function(err, result){
if (err){
throw err;
}
var numFound = result.length;
if (numFound == 1) {
//session was found
var userID = result[0].user_id;
returnData.push(result[0].user_id);
var sql2 = "SELECT * FROM users WHERE id=?";
db.query(sql2, [userID], function(err, result){
if (err){
throw err;
}
var uName = result[0].username;
returnData.push(result[0].username);
return callback(returnData);
});
}
});
}
And the callback function:
getUserSession(data.token, function(result){
newUserID = result[0];
newUsersName = result[1];
socket.broadcast.emit('newclient',socket.player);
});
I would do something like this:
function sqlQuery(sql, params) {
return new Promise((resolve, reject) => {
db.query(sql, params, function(err, result) {
if (err) {
return reject(err);
}
return resolve(result);
});
});
}
function getUserSession(sessionKey, callback){
const sql = "SELECT * FROM game_sessions WHERE unique_key=? AND still_active=?";
const stillActive = 1;
let returnData = [];
try {
return sqlQuery(sql, [sessionKey, stillActive])
.then(result => {
if (result.length === 1) {
//session was found
const userID = result[0].user_id;
returnData.push(result[0].user_id);
const sql2 = "SELECT * FROM users WHERE id=?";
return sqlQuery(sql2, [userID])
.then(result => {
const uName = result[0].username;
returnData.push(result[0].username);
return callback(returnData);
})
}
})
} catch (err) {
//handle err
}
}
Edit: if the callback function being passed in is an aync function, you'll probably need to modify the above snippet to await it.
I am trying to get result from function getWeather() in Nodejs to respone it to json in one router but I can not get it.
var request = require('request');
var publicIp = require('public-ip');
function getCity (userip){
var url = `https://ipinfo.io/${userip}/json`;
request(url, (err, respone, body)=>{
var data = JSON.parse(body);
var city = data['city'];
return getLocationKey(city);
})
}
function getLocationKey(city){
var url = `http://dataservice.accuweather.com/locations/v1/cities/search?q=${city}&apikey=${API_KEY}`;
request(url, (err, respone, body)=>{
var data = JSON.parse(body);
var key = data[0].Key;
return getWeather(key);
})
}
function getWeather(key){
var url = `http://dataservice.accuweather.com/forecasts/v1/daily/1day/${key}?apikey=${API_KEY}`;
request(url, (err, respone, body)=>{
var weather = JSON.parse(body);
console.log("weather: " + weather);
return weather;
})
}
I have got result from getCity() and getLocationKey(), but when get final result from getWeather() is not successfull.
I console.log weather is Object object. I try to sepate it and call it only, it respone for me weatherDetails as images
router.get('/weather-weather', (req, res)=>{
var city = 'hanoi';
var key = '353412'
var url = `http://dataservice.accuweather.com/forecasts/v1/daily/1day/${key}?apikey=${API_KEY}`;
request(url, (err, respone, body)=>{
var weatherDetails = JSON.parse(body);
res.json(weatherDetails);
})
})
However, I want to call it in this route to respone a json but it fail
router.get('/weather', (req, res)=>{
publicIp.v4()
.then(userip=>{
console.log("userIP: " + userip);
getCity(userip);
})
.catch(err=>{
console.log('Error: '+ err);
})
})
But it failed. I don't know how to return respone result from getWeather() function. How I can get it?
The function getXXX cannot get the "return" inside the callback function.
And you did not call res.json to send the result to the client.
You could pass res to getXXX and use it in this way:
function getCity(userip, res) {
var url = `https://ipinfo.io/${userip}/json`;
request(url, (err, respone, body) => {
var data = JSON.parse(body);
var city = data['city'];
return getLocationKey(city, res);
})
}
function getLocationKey(city, res) {
var url = `http://dataservice.accuweather.com/locations/v1/cities/search?q=${city}&apikey=${API_KEY}`;
request(url, (err, respone, body) => {
var data = JSON.parse(body);
var key = data[0].Key;
return getWeather(key, res);
})
}
function getWeather(key, res) {
var url = `http://dataservice.accuweather.com/forecasts/v1/daily/1day/${key}?apikey=${API_KEY}`;
request(url, (err, respone, body) => {
var weather = JSON.parse(body);
console.log("weather: " + weather);
res.json(weather);
})
}
router.get('/weather', (req, res) => {
publicIp.v4()
.then(userip => {
getCity(userip, res);
})
.catch(err => {
console.log('Error: ' + err);
})
})
I want to return database value in node js and pass as a variable in ejs file.
Bellow is the code, Which I used. it did not return value.
function getExternalLocation(cb) {
mssql.connect(msSqlSettings, function (err ) {
if (err) {
cb(err);
}
var getQuery = "SELECT [Title] FROM [dbo].[StyleTemplates] " ;
//console.log(getQuery);
var request = new mssql.Request();
// query to the database and get the data
request.query(getQuery, function (err, rows) {
mssql.close();
cb(err, rows);
});
});
}
exports.eejsBlock_editbarMenuLeft = function (hook_name, args, cb) {
var userData = getExternalLocation(args, function(err, rows) {});
args.content = args.content + eejs.require(
'ep_resources/templates/editbarButtons.ejs', {
userData: userData
});
return cb();
})
userData did not return any value.
var userData = getExternalLocation(args, function(err, rows) {});
I don't think userData will get right data in async function, there is no await, so you can try to get data in callback.
getExternalLocation(args, function(err, rows) {
var userData = rows;
args.content = args.content + eejs.require(
'ep_resources/templates/editbarButtons.ejs', {
userData: userData
});
});
I did a restful delete to remove a record by id.. It didn't return me any error, but the record isn't get removed in my collection
my route
app.delete('/api/genres/:id',function(req,res){
var id = req.params._id;
var genre = req.body;
Genres.deleteGenre(id, function(err,genre){
if(err){
throw err;
}
res.json(genre)
})
});
my model (I'm using mongoose)
//Delete Genre
module.exports.deleteGenre = function (id, callback) {
var query = {_id: id};
Genre.remove(query, callback);
}
it even return ok status with
{"ok":1,"n":0}
app.delete('/api/genres/:id',function(req,res){
var id = req.params.id;
Genres.deleteGenre(id, function(err,genre){
if(err){
throw err;
}
res.json(genre)
})
});
//Delete Genre
module.exports.deleteGenre = function (id, callback) {
var query = {_id: id};
//use this to findByIdAndRemove in mongoose, it will work
Genre.findByIdAndRemove(query, callback);
}
you don't need to take anything in var genre = req.body
Try this!!!
Happy Coding!!!
use findById to get the document first then you will be able to remove them
Genre.findById(req.params.id, function(err, genre){
if(err) { return res.send(500, err); }
genre.remove(function(err){
if(err) { return res.send(500, err); }
return res.send(204);
});
});