How to get result from function in other file in node.js - javascript

Trying to call database query from other javascript file in NodeJS.
Sample database file:
function addUser(user) {
connection.connect(function (err) {
if (err) {
console.error('Error connecting: ' + err);
}
console.log('Connected as id ' + connection.threadId);
});
var sql = "INSERT INTO `mobile`.`main` (`userId`) VALUES (?);"
var inserts = [user];
connection.query(sql, inserts, function (error, results) {
console.log('query');
if (error) {
return error;
} else {
console.log('Success Query');
return results;
}
});
connection.end(function (err) {
if (err) {
console.error('Error connecting: ' + err);
}
console.log('Connection closed!');
});
}
module.exports = addUser;
Sample main.js file:
app.get('/api/mysql/:user', function (req, res) {
var user = req.params.user;
addUsers(user)
res.json({
SQLResp: 'Query succes',
result: addUsers.result
});
});
How to get the result from the first file and use it as a response in the main js?

Welcome to stack overflow.
this is missing from your database file, How did you got connection there?
Here's a sample example over How to export database connection and use this to make calls from other files.
Also do read about callbacks-functions, Promises, async-await and Asynchronous functions of JavaScript. These are basics of JavaScript and also do go through NodeJS docs.
DB.js:
const MYSQL = require('mysql');
const connection = MYSQL.createConnection({
host: 'localhost', // url of db
user: 'root',
password: 'root',
database: 'dbName'
});
module.exports = connection;
Now will use this connection from other file to call database.
app.js:
const db = require('./DB'); // Path of your db connection file. I named it DB.js on same level as of app.js
function addUser(user) {
// Since database calls are async in NodeJS thus using promises.
return new Promise ( (resolve, reject) => {
db.connect(function (err) {
if (err) {
console.error('Error connecting: ' + err);
return reject(err);
}
console.log('Connected as id ' + connection.threadId);
});
var sql = "INSERT INTO `mobile`.`main` (`userId`) VALUES (?);"
var inserts = [user];
db.query(sql, inserts, function (error, results) {
console.log('query');
if (error) {
return reject(err);
} else {
console.log('Success Query');
return resolve(results);
}
});
db.end(function (err) {
if (err) {
console.error('Error connecting: ' + err);
}
console.log('Connection closed!');
});
});
}
app.get('/api/mysql/:user', function (req, res) {
var user = req.params.user;
addUsers(user)
.then (result => { // When addUsers will resolve promise will be in then.
res.json({
SQLResp: 'Query succes',
result: result
});
})
.catch(err => { // If promise is rejected then on catch
res.json({
SQLResp: 'Query err',
result: err
});
});
});

You need to pass a callback into your addUser function, and call it inside your connection.query with the results.
Currently, when you return, you're returning inside another callback, which means the data is more or less being thrown away.
That will also let you handle all of the error cases in a way you can tell the user about.

Related

How to correctly write module in Node.JS?

So I'm trying to make it so I don't have to have multiple connections to my database when I can just put my connection and runQuery function in a file and just require it in another file. Here is what I have in my "mysql.js" file.
const mysql = require('mysql');
module.exports = function () {
let connection = mysql.createConnection({
host: '------',
user: 'voltclou_site',
password: '----',
database: process.env.database
})
connection.connect(function(err) {
if (err) {
console.error('[DATABASE] Error connecting: ' + err.stack);
return;
}
console.log('[DATABASE] Connected as id ' + connection.threadId);
});
async function runQuery(query, values) {
return new Promise((resolve, reject) => {
connection.query(query, values, function (error, results) {
if (error) return reject(error)
return resolve(results)
})
})
}
}
Here is how I would like to require it in my files:
const { connection, runQuery } = require('./functions/mysql')
Am I doing this correctly? I'm new to this whole module thing. I've been trying to split my files up because one index.js with 3000+ lines is insane. Thanks for any help.
No you didnt do it correclty. What you have done you have exported it as an default but you want to export named functions. You can do it like:
const mysql = require("mysql");
let connection = mysql.createConnection({
host: "81.19.215.6",
user: "voltclou_site",
password: "yogO{6,F#8WS",
database: process.env.database
});
connection.connect(function(err) {
if (err) {
console.error("[DATABASE] Error connecting: " + err.stack);
return;
}
console.log("[DATABASE] Connected as id " + connection.threadId);
});
async function runQuery(query, values) {
return new Promise((resolve, reject) => {
connection.query(query, values, function(error, results) {
if (error) return reject(error);
return resolve(results);
});
});
}
module.exports = {
connection,
runQuery
};
The value you've described, { connection, runQuery }, should be the value assigned to module.exports:
const mysql = require('mysql');
let connection = mysql.createConnection({ ... });
connection.connect(...);
let runQuery = async (query, values) => { ... };
module.exports = { connection, runQuery };
You may not even need to export connection, if all you need elsewhere is runQuery!

`Cannot set headers after they are sent to client` error when using mysql2 async/await

I am changing my backend (switching over from Mongo to MySql). I know the error is getting thrown because a return statement is being executed before my SQL query has finished and then when my sql query finishes, it tires to send another res.send, hence why I am trying to use mysql2 with Promise wrappers to use await on queries in my async function.
I have a separate file that creates the DB connection so I can access the connection throughout my Nodejs backend:
const mysql = require('mysql2');
async function pool(){
const pool = await mysql.createPool({
host: "ip",
user: "username",
password: "password",
database: "db"
});
return pool
}
exports.getConnection = async function(callback) {
const currentPool = await pool();
currentPool.getConnection(function(err, conn) {
if(err) return callback(err);
callback(err,conn)
});
};
Then, to create a query that follows async/await:
sql.getConnection(async function(err, client){
client.query(`select email from users where email = "${email}"`, function (error, result){
if(error) return res.status(500).send('an internal db error occurred');
// carry on with code ...
});
});
I've tried using await on the query too:
await sql.getConnection(async function(err, client){
client.query(`select email from users where email = "${email}"`, function (error, result){
if(error) return res.status(500).send('an internal db error occurred');
// carry on with code ...
});
});
What am I missing? I haven't tired to use the normal mysql NPM library and make my own promise wrapper yet...
NEW CODE:
I've updated my function:
const mysql = require('mysql2');
const pool = mysql.createPool({
host: "ip",
user: "user",
password: "pass",
database: "db"
});
exports.db = (sql) => {
new Promise((resolve, reject) => {
pool.getConnection((err, conn) => {
if(err) return reject(err);
conn.query(sql, (err, results, fields) => {
conn.release()
if(err) return reject(err)
console.log(results)
resolve(results);
});
});
});
}
Then I call it via:
try{
const emailExisit = await sql.db(`SELECT email FROM users WHERE email = "${email}"`);
console.log(emailExisit);
if(emailExisit.length > 0) return res.status(422).send({"data": "", "code": "105", "message": "An account with given email already exists"});
}catch (err) {
console.log(err)
return res.status(500).send({"data": "", "code": "108", "message": `There seems to be an error contacting the database. Try again later <br> ${err}`});
}
However, my code still continues, leaving my emailExists variable undefined (yes, it is inside an async function)
This is my configuration to use MySQL with Node.js. I hope it works with you.
/config/mysql.js
const mysql = require('mysql2');
const pool = mysql.createPool({
host: process.env.MYSQL_HOST,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
port: process.env.MYSQL_PORT,
database: process.env.MYSQL_DB_NAME,
});
const query = (query, args = []) =>
new Promise((resolve, reject) => {
pool.getConnection((err, connection) => {
if (err) {
return reject(err);
}
connection.query(query, args, (err, results) => {
connection.release();
if (err) {
return reject(err);
}
resolve(results);
});
});
});
module.exports = { query };
/index.js
const { query } = require('./mysql');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.get('/api/v1/sum', (req, res) => {
query('SELECT 1 + 1 as sum')
.then(results => {
res.json({ sum: results[0].sum });
})
.catch(err => {
console.error(err);
res.status(500).json({ error: 'error msg' });
});
});
// anther example with async
app.get('/api/v1/sum', async (req, res) => {
try {
const results = await query('SELECT 1 + 1 as sum');
res.json({ sum: results[0].sum });
} catch (err) {
console.error(err);
res.status(500).json({ error: 'error msg' });
}
});
app.listen(3000);

Node MYSQL exports returns undefined

I am creating a discord bot that has integration with mysql. To make it easier, I created a central file for the mysql database (configs/mysql.js) and, when the command needs it, it will send the query request to that file and finally, it will return the processed value. But when I try to do this, the return is undefined in the console (of the command), but in the mysql.js console, it shows the correct value.
MYSQL.js Code
const mysql = require("mysql");
const connection = mysql.createConnection({
host: config.URL,
user: config.dbUser,
password: config.dbPassword,
database: config.database
});
connection.connect(function(err) {
if (err) {
console.error("[MYSQL] Error on Connection: " + err.stack);
return;
}
console.log("[MYSQL] Connected with ID " + connection.threadId + "!");
});
function query(sql) {
connection.query(sql, function(error, result, fields) {
if (error) return error;
const analise = JSON.stringify(result[0]);
console.log(analise) //it's return the value correct
return analise
});
}
exports.connection = connection;
exports.query = query;
The Request
const status1 = await mysql.query("SELECT `status` FROM `server_status`");
console.log(status1); //it's return undefined
Can anyone help me?
Use promise for mysql you can`t use return in callback function.
const mysql = require('mysql');
const connection = mysql.createConnection({
host: config.URL,
user: config.dbUser,
password: config.dbPassword,
database: config.database,
});
connection.connect(function(err) {
if (err) {
console.error('[MYSQL] Error on Connection: ' + err.stack);
return;
}
console.log('[MYSQL] Connected with ID ' + connection.threadId + '!');
});
function query(sql) {
return new Promise(resolve => {
connection.query(sql, function(error, result, fields) {
if (error) return error;
const analise = JSON.stringify(result[0]);
console.log(analise); //it's return the value correct
resolve(analise);
});
});
}
exports.connection = connection;
exports.query = query;
const status1 = await mysql.query("SELECT `status` FROM `server_status`");

Node.js module export "pre-load"

This is in a mysql.js file:
const mysql = require('mysql');
const config = require('./config.json');
const con = mysql.createConnection({
host: config.dbhost,
user: config.dbuser,
password: config.dbpass,
database: config.dbname,
});
module.exports = {
findUser: function(email) {
const sql = 'SELECT * FROM users WHERE email = ' + mysql.escape(email);
con.connect(function(err) {
if (err) throw err;
console.log('Connected!');
con.query(sql, function(err, result) {
if (err) throw err;
return result[0].id;
});
});
},
};
then within my index.js file there is this:
const mysql = require('./mysql.js');
console.log(mysql.findUser('example#example.test'));
When the code is running, it outputs "undefined" and then "Connected!" after the db connection is made. Even though if I do a console.log on result[0].id it outputs 1, which is the correct id...
Question: How can I load the mysql.js file first before the function is called?
You need to wait for response cause its an asynchronous function.
Try using callback or promises.
Callback example:
mysql.findUser('example#example.test', function(res)){ console.log(res)});
module.exports = {
findUser: function(email, callback) {
const sql = 'SELECT * FROM users WHERE email = ' + mysql.escape(email);
con.connect(function(err) {
if (err) throw err;
console.log('Connected!');
con.query(sql, function(err, result) {
if (err) throw err;
callback(result[0].id);
});
});
},

Last callback not being called using async

I cannot seem to get the last callback (commented as "optional callback") called to send the result back to the browser. Any pointers as to what I am doing wrong? I am using the following modules: async, restify and postgresql for node.js
console.log('Start');
var async = require('async');
var restify = require('restify');
var server = restify.createServer();
server.use(restify.bodyParser());
server.get('/user/creationdate/:username', function(req, res, next) {
var userName = req.params.username;
var record;
async.parallel([
function(callback){
getUserByName(userName, function(err, user) {
if (err) return callback(err);
record = user;
});
}
],
// optional callback
function(err){
console.log('5. Following record has been retrieved:' + record);
res.send(record);
});
next();
});
server.listen(8080, function () {
console.log('%s listening at %s', server.name, server.url);
});
handleError = function handleError(err) {
if(!err) { return false; }
else {
console.log('The following error occurred:' + err);
}
return true;
};
function getPgClient(){
var pg = require('pg');
var client = new pg.Client({
user: 'postgres',
password: 'password',
database: 'foobar',
host: '192.168.1.100',
port: 5432
});
client.on('drain', client.end.bind(client)); //disconnect client when all queries are finished
return client;
}
function getUserByName(userName, callback){
var client = getPgClient();
console.log('2. Trying to connect to DB');
client.connect(function(err) {
console.log('3. Error connecting to DB:' + handleError(err));
if(handleError(err)) return callback(err);
client.query("SELECT created_at FROM users WHERE username='" + userName + "'", function(err, result) {
if(handleError(err)) return;
console.log('4. Error occurred:' + err);
console.log(result);
console.log(callback);
callback(null, result);
})
});
}
I'm not sure why you're using async since you're only calling one asynchronous function. But the reason your callback isn't called is because you're not ending the first function by calling its callback:
async.parallel([
function(callback) {
getUserByName(userName, function(err, user) {
// call async callback with err and user
callback(err, user);
});
}
], function(err, record) {
console.log('5. Following record has been retrieved:' + record);
res.send(record);
});
Or, shorter:
async.parallel([
function(callback) {
getUserByName(callback);
}
], function(err, record) {
console.log('5. Following record has been retrieved:' + record);
res.send(record);
});
Or, in this case, even shorter (and without the need for async):
getUserByName(function(err, record) {
// handle error, or ...
console.log('5. Following record has been retrieved:' + record);
res.send(record);
});
Saw my mistake, missing the line where I should have returned the callback as in:
async.parallel([
function(callback){
getUserByName(userName, function(err, user) {
if (err) return callback(err);
record = user;
return callback(null, record);
});
}

Categories

Resources