I am trying to create a node.js server that would handle a POST request that would have data into two different MySQL tables.
Here the code behind my node.js server.
let mysql = require("mysql");
const http = require('http');
http.createServer(async function(req, res) {
let con = mysql.createConnection({
host: "...",
user: "...",
password: "...",
database: "..."
});
res.writeHead(200, {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
});
if (req.method == 'POST') {
let body = '';
req.on('data', function(data) {
body += data.toString();
if (body.length > 10000000) {
http.request.connection.destroy();
}
});
req.on('end', () => {
if (body) {
let item = JSON.parse(body);
addQuestion(con, item.title).then(function(result){
con.end();
addOptions(con, result.insertId, item.options).then(function(data){
con.end();
res.end(JSON.stringify({
message: "Saved!"
}));
});
});
}
});
return;
}
res.end(JSON.stringify({
message: "OK!"
}));
}).listen(80);
function addQuestion(con, title) {
return new Promise((resolve, reject) => {
con.connect(function(err) {
if (err) return reject(err);
let sql = "INSERT INTO _questions SET ?";
con.query(sql, {title: title}, function(err, result, fields) {
if (err) return reject(err);
return resolve(result);
});
});
});
}
function addOptions(con, questionId, options) {
return new Promise((resolve, reject) => {
con.connect(function(err) {
if (err) return reject(err);
let values = [];
for(let x = 0 ; x < options.length; x++){
let option = options[x];
values.push({
title: option.title,
is_correct: option.isCorrect,
question_id: questionId
});
}
let optionsSql = "INSERT INTO _options (title, is_correct, question_id) VALUES ?";
con.query(questionSql, values, function(err, requestData) {
if (err) return reject(err);
return resolve(result);
});
});
});
}
I am getting the following error
UnhandledPromiseRejectionWarning: Error: Cannot enqueue Handshake
after already enqueuing a Handshake.
How can I solve this issue?
**If you using the node-MySQL module, just remove the .connect and .end. Just solved the problem myself.
**
Related
I have a user schema as follows:
const UserSchema = new mongoose.Schema({
skills: [String]
});
module.exports = mongoose.model("User", UserSchema);
And a Fetch request to delete a skill as follows:
const deleteItem = async (id) => {
try {
await fetch(`http://localhost:5000/api/user/deleteskill`, {
method: "DELETE",
headers: { "Content-Type": "application/JSON", token: accessToken },
body: JSON.stringify({ userid: userid , skill:id}),
})
.then((res) => res.json())
.then((data) => {
console.log("USER SKILLS:", data.userskills);
});
} catch (err) {
console.log(err);
}
};
Server
const deleteSkill = async (req, res) => {
try {
const user = await User.findById(req.body.userid)
//user.skills.pull(req.body.skill);
// removeskill = user.skills.filter(function(item) {
// return item !== req.body.skill
// })
if (user.skills.includes(req.body.skill)) {
res.status(400).json("Item Still Exists");
} else {
res.status(200).json("Item Deleted");
}
} catch (error) {
res.status(500).send({ error: error.message });
}
};
the array is in the following structure
[
'skill1', 'java', 'skill5'
]
I have tried to remove the user skill from the array in several ways but I still get res.status(400).json("Item Still Exists");. What I'm doing wrong?
Use the findOneAndUpdate method to find a document with the user id and update it in one atomic operation:
const deleteSkill = async (req, res) => {
try {
let message = "Item Deleted";
let status = 200;
const user = await User.findOneAndUpdate(
{ _id: req.body.userid },
{ $pull: { skills: req.body.skill } },
{ new: true }
)
if (user && user.skills.includes(req.body.skill)) {
message = "Item Still Exists";
status = 400;
} else if (!user) {
message = "User Not Found";
status = 404;
}
res.status(status).send({ message });
} catch (error) {
res.status(500).send({ error: error.message });
}
};
I believe you want to remove skills from the database then the following function could help you out.
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("mydb");
var myquery = { userid: userid, skillid: skillid};
dbo.collection("skills").deleteOne(myquery, function(err, obj) {
if (err) throw err;
console.log("1 document deleted");
db.close();
});
});
You have a method of removing elements from arrays, if you want to remove the first one you could use array.shift (more on it here), but if you want to delete it completely from your database you could always, find it and then update it.
User.update({ _id: userid }, { $pull: { "skills": "[skill]" }})
Earlier I am working with the single connection but now I am trying to create a DB Pool in Nodejs using Mysql.
I am following the Single Pattern or Class-Based Pattern to create a query and other operations
Earlier Configuration (Everything working fine)
const connection = mysql.createConnection({
host: dbConfig.HOST,
user: dbConfig.USER,
password: dbConfig.PASSWORD,
database: dbConfig.DB
});
connection.connect();
connection.query("SET AUTOCOMMIT=false;", (err) => {
if(err){
console.log(err)
console.log("Couldn't set auto commit to false")
}else{
console.log("AutoCommit set to false")
}
});
function query(sql, params, autorollback) {
return new Promise((resolve, reject) => {
//let currentTime = new Date().valueOf();
let query = connection.query(sql, params, (err, resp) => {
if(err && autorollback) {
return resolve(rollback(err));
}
else if (err) {
console.log(err)
return reject(err);
}
//console.log("Time Taken: ", new Date().valueOf() - currentTime, "\n", query.sql);
//console.log(resp);
resolve(resp);
});
});
}
Create Pool Configuration (Didn't get the response from the query)
const connection = mysql.createPool({
host: dbConfig.HOST,
user: dbConfig.USER,
password: dbConfig.PASSWORD,
database: dbConfig.DB,
connectionLimit: 4,
});
connection.getConnection(function (err, conn) {
conn.query("SET AUTOCOMMIT=false;", (err) => {
if (err) {
console.log(err)
console.log("Couldn't set auto commit to false")
} else {
console.log("AutoCommit set to false")
}
});
});
function query(sql, params, autorollback) {
console.log(sql)
return new Promise((resolve, reject) => {
//let currentTime = new Date().valueOf();
connection.getConnection(function (err, conn) {
if (err) {
console.log(err)
return reject(err);
}
let query = conn.query(sql, params, (err, resp) => {
console.log(sql)
if (err && autorollback) {
return resolve(rollback(err));
}
else if (err) {
console.log(err)
return reject(err);
}
//console.log("Time Taken: ", new Date().valueOf() - currentTime, "\n", query.sql);
//console.log(resp);
resolve(resp);
conn.release();
});
})
});
}
You don't have to set autocommit false here.
The beginTransaction()-method sets the autocommit to false by default. You have explicitly call conn.commit() in order to have the queries inside your beginTransaction() to have any effect here.
connection.getConnection(function (err, conn) {
conn.beginTransaction((err) => {
conn.query("YOUR_SQL_QUERY_GOES_HERE", (err) => {
if (err) {
conn.commit();
} else {
console.log("Failed")
}
});
}
});
Whenever I hit this api with sending this
[{"project_id": "knsfviv9",
"coach_id": ""
},
{"project_id": "ovsijiov9",
"coach_id": ""
}]
it inserts into database but it gives response 0 as the result variable remains 0. result variable gets incremented but in res.send it sends 0.
can someone help me with this?
app.post('/api/patc/:id', (req, res) => {
let projectList = req.body;
projectList.forEach(element => {
let data = {
patc_id: "patc-" + randomID(),
college_id: req.params.id,
project_id: element.project_id,
coach_id: element.coach_id,
date: NOW()
};
let sql = "INSERT INTO projects_assigned_to_colleges SET ?";
conn.query(sql, data, (err, results) => {
if (err) throw err;
result.push(results);
});
});
res.send(JSON.stringify({ "status": 200, "error": null, "response": result }));
});
You are trying to execute asynchronous code in forEach which is giving you undesired behavior. Change the code to something like this
app.post("/api/patc/:id", async (req, res) => {
let projectList = req.body;
var result = 0;
const result = await Promise.all(projectList.map(element => {
let data = {
patc_id: "patc-" + randomID(),
college_id: req.params.id,
project_id: element.project_id,
coach_id: element.coach_id,
date: NOW()
};
return new Promise((resolve, reject) => {
let sql = "INSERT INTO projects_assigned_to_colleges SET ?";
conn.query(sql, data, (err, results) => {
if (err) throw err;
resolve(results);
});
});
}));
res.send(JSON.stringify({ status: 200, error: null, response: result }));
});
My problem is, I want to make INSERT query for every object from JSON using some loop, but I almost always got an error "Cannot set headers after they are sent to the client".Can someone help?Tnx
const connection = require('./config');
module.exports.excel = function (req, res) {
var _query = 'INSERT INTO excel (id, first_name, last_name) values ?';
var jsonData = req.body;
var values = [];
function database() {
return new Promise((resolve, reject) => {
jsonData.forEach((value) => {
values.push([value.id, value.first_name, value.last_name]);
connection.query(_query, [values], (error, results) => {
if (error) {
reject(
res.json({
status: false,
message: error.message
}))
} else {
resolve(
res.json({
status: true,
data: results,
message: 'Excel file successfully created in database'
}))
}
});
});
})
}
async function write() {
await database();
}
write();
}
After I got JSON from my Angular 6 front I put req.body into jsonData and try with forEach to put every object("value" in this case) into query and write that into Excel file.
You will have to wrap each query in a Promise and wait for all to complete before sending the response using Promise.all
Not that database() is going to throw when one of the queries fail and you won't have any access to the resolved promises.
const connection = require('./config');
module.exports.excel = function(req, res) {
const _query = 'INSERT INTO excel (id, first_name, last_name) values ?';
const jsonData = req.body;
function database() {
return Promise.all(
jsonData.map(
value =>
new Promise((resolve, reject) => {
const values = [value.id, value.first_name, value.last_name]
connection.query(_query, [values], (error, results) => {
if (error) {
reject(error.message);
return;
}
resolve(results);
});
})
)
);
}
async function write() {
try {
const results = await database();
res.json({
status: true,
data: results,
message: 'Excel file successfully created in database'
});
} catch (e) {
res.json({
status: false,
message: e.message
});
}
}
write();
};
I have problem with my node.js bot to roulette. Bot is fully set up but when I launching it, it gives me error "Bot stopped with code null". Can someone help me to fix it?
Here is the error screenshot: http://i.imgur.com/zfZoMD4.png
Code:
function login(err, sessionID, cookies, steamguard) {
if(err) {
logger.error('Auth error');
logger.debug(err);
if(err.message == "SteamGuardMobile") {
account.twoFactorCode = SteamTotp.generateAuthCode(account.shared_secret);
logger.warn('Error in auth: '+account.twoFactorCode);
setTimeout(function() {
community.login(account, login);
}, 5000);
return;
}
process.exit(0);
}
logger.trace('Sucesfully auth');
account.sessionID = sessionID;
account.cookies = cookies;
community.getWebApiKey('csgobananas.com', webApiKey);
community.startConfirmationChecker(10000, account.identity_secret);
}
function webApiKey(err, key) {
if(err) {
logger.error('Cant make apikey')
logger.debug(err);
process.exit(0);
return;
}
account.key = key;
logger.trace('API key bot '+account.accountName+' '+account.key);
offersSetup();
community.loggedIn(checkLoggedIn);
}
function offersSetup() {
logger.trace('Loaded steam-tradeoffers');
offers.setup({
sessionID: account.sessionID,
webCookie: account.cookies,
APIKey: account.key
});
}
function checkLoggedIn(err, loggedIn, familyView) {
if((err) || (!loggedIn)) {
logger.error('We arent logged in')
process.exit(0);
} else {
logger.trace('Logged in');
account.auth = true;
bot_manager.js code:
var forever = require('forever-monitor');
var mysql = require('mysql');
var pool = mysql.createPool({
connectionLimit : 10,
database: 'placeholder',
host: 'placeholder',
user: 'placeholder',
password: 'placeholder'
});
query('SELECT * FROM `bots`', function(err, row) {
if((err) || (!row.length)) {
console.log('Failed request or empty bot table');
console.log(err);
return process.exit(0);
}
console.log('List of bots:');
row.forEach(function(itm) {
console.log('Launching bot# '+itm.id);
var bot = new (forever.Monitor)('bot.js', {
args: [itm.id]
});
bot.on('start', function(process, data) {
console.log('Bot with ID '+itm.id+' started');
});
bot.on('exit:code', function(code) {
console.log('Bot stopped with code '+code);
});
bot.on('stdout', function(data) {
console.log(data);
});
bot.start();
});
});
function query(sql, callback) {
if (typeof callback === 'undefined') {
callback = function() {};
}
pool.getConnection(function(err, connection) {
if(err) return callback(err);
console.info('Database connection ID: '+connection.threadId);
connection.query(sql, function(err, rows) {
if(err) return callback(err);
connection.release();
return callback(null, rows);
});
});
}