How to call a javascript function inside another function in node js - javascript

I have a file index.js as below. Where I am trying to call a async function getConn in other function createThumbnails. But I am getting the error as "failed to connect to DEDC: 1433 - self signed certificate" in the catch block.
const sharp = require('sharp');
const sql = require('mssql')
// CONNECTION CONFIGURATION OF BASE DB
async function getConn() {
try {
const config = {
user: 'sa_user',
password: '*******',
server: 'DEDC',
database: 'DEMO_BASE'
}
const pool = await new sql.ConnectionPool(config)
const req=await pool.connect()
const conn = await req.request()
return conn;
} catch (err) {
return err;
}
};
const createThumbnails = async() => {
try{
var conn = await getConn();
const query = `exec DBBASE.get_client_info`
var clientusers = await conn.query(query);
} catch (err) {
return err;
}
}
createThumbnails()
How do I exactly call the function getConn inside createThumbnails. Please help. Thanks in advance

It's because you are using variable with the same name as the function.
Try different name:
var conn = await getConn();
const query = `exec DBBASE.get_client_info`
var clientusers = await conn.query(query);

You encounter what called hoisting. Kyle Simpson has a great explaination on this topic
var getConn = await getConn();
which means getConn will be initialized first, before assignment, which equivalents to
var getConn // initialized
getConn = await getConn() // assignment
Then turned out that you got the error
Solution here is to store it in a different variable name, like
var conn = await getConn();
async function getConn() {
return {
query: async () => {
console.log("query called");
},
};
}
const createThumbnails = async () => {
try {
var conn = await getConn();
const query = `exec DBBASE.get_client_info`;
var clientusers = await conn.query(query);
} catch (err) {
console.log(err);
}
};
createThumbnails();

We need to use trustServerCertificate: true in DB configuration i.e in const config

Related

Close MONGODB connection after data insertion

I want to populate my database with some random data. I have used Faker.js for generating that data. I'm using MongoDB on my localhost and all the data is properly following all the validation rules from the schema. I'm having problem with the closing connection of my connection after insertion of data. I want to close the connection soon after the data is populated. I'm using async function to be aware of all the things but something is not going right.
Here is my code seeds.js which is the script im using to populate database
const path = require("path");
require("dotenv").config({ path: path.resolve(__dirname, "../.env") });
var mongoose = require("mongoose");
mongoose.connect(process.env.MONGODB_URI);
require("../models/User");
require("../models/Item");
require("../models/Comment");
var Item = mongoose.model("Item");
var Comment = mongoose.model("Comment");
var User = mongoose.model("User");
const ItemData = require("../data/item.json");
const CommentData = require("../data/comment.json");
const UserData = require("../data/user.json");
async function InsertData() {
ItemData.forEach(async (item) => {
item.seller = item.seller.$oid;
const oldItem = await Item.find({ title: item.title });
if (!oldItem.length) {
var newItem = new Item(item);
await newItem.save();
} else {
console.log(item.slug);
}
});
UserData.forEach(async (user) => {
const oldUser = await User.find({ username: user.username });
if (!oldUser.length) {
var user = new User(user);
await user.save();
} else {
console.log(user.username);
}
});
CommentData.forEach(async (comment) => {
comment.item = comment.item.$oid;
comment.seller = comment.seller.$oid;
var newComment = new Comment(comment);
const oldComment = await Comment.find({ _id: newComment.id });
if (!oldComment.length) {
await newComment.save();
} else {
console.log(comment.body);
}
});
}
async function cleanup() {
await Item.deleteMany({}, () => console.log("Data Cleared Item"));
await Comment.deleteMany({}, () => console.log("Data Cleared Comment"));
await User.deleteMany({}, () => console.log("Data Cleared User"));
}
async function main() {
InsertData().then(async () => {
console.debug('Data Inserted. Closing connection.');
await mongoose.connection.close();
});
}
main();
Here is the stack trace of the error
/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/core/connection/pool.js:841
cb(new MongoError('pool destroyed'));
^
MongoError: pool destroyed
at Pool.write (/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/core/connection/pool.js:841:8)
at _command (/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/core/wireprotocol/command.js:120:10)
at command (/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/core/wireprotocol/command.js:28:5)
at Object.query (/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/core/wireprotocol/query.js:66:3)
at Server.query (/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/core/topologies/server.js:644:16)
at FindOperation.execute (/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/operations/find.js:38:12)
at /Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/operations/execute_operation.js:144:17
at Server.selectServer (/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/core/topologies/server.js:832:3)
at Server.selectServer (/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/topologies/topology_base.js:342:32)
at executeWithServerSelection (/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/operations/execute_operation.js:131:12)
at /Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/operations/execute_operation.js:70:9
at maybePromise (/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/utils.js:685:3)
at executeOperation (/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/operations/execute_operation.js:34:10)
at Cursor._initializeCursor (/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/core/cursor.js:534:7)
at Cursor._initializeCursor (/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/cursor.js:186:11)
at nextFunction (/Users/karnikkanojia/Desktop/Anythink-Market-21cto/backend/node_modules/mongodb/lib/core/cursor.js:737:10)
error Command failed with exit code 1.

Mongoose data Writing issue in Javascript

Just started with a javascript couple of days back. I am trying to use MongoDB with mongoose to write the data but it is not writing even though the connection is established.
I would really appreciate it if you can help me point out what I am missing here.
dbtest.js - module to create connection
require("dotenv").config();
const mongoose = require("mongoose");
const Block = require("./model/blockSchema");
const connectDB = async () => {
try {
await mongoose.connect(process.env.DATABASE_URI, {
useUnifiedTopology: true,
useNewUrlParser: true,
});
console.log("CONNECTED to MONGODB DATABASE");
} catch (err) {
console.error(err);
}
};
module.exports = connectDB;
blockchain.js
Even though I have verified the connection before calling the main method, it looks like the connection is not available to class methods.
require("dotenv").config();
const { hash256 } = require("../util/util");
const block = require("./block");
const blockchain = require("./blockHeader");
const Block = require("../database/model/blockSchema");
const { mongoose } = require("mongoose");
const connect = require("../database/dbtest");
VERSION = 1;
const ZERO_HASH = String("0").padStart(64, "0");
// Create connection
connect();
class Blockchain {
GenesisBlock() {
try {
const BlockHeight = 0;
const prevBlockHash = ZERO_HASH;
this.addBlock(BlockHeight, prevBlockHash);
} catch (err) {
console.log(`Error in Genesis Blockchain Function \n ${err}`);
}
}
addBlock(BlockHeight, prevBlockHash) {
let timestamp = Date.now();
let Transaction = `Codies Alert sent ${BlockHeight} to Anni`;
let merkleRoot = hash256(Transaction);
let bits = "ffff001f";
let blockHeader = new blockchain.BlockHeader(
VERSION,
prevBlockHash,
merkleRoot,
timestamp,
bits
);
//Mine a Block
blockHeader.mine();
// Create Schema Instance to Write the data
let BlockObj = new Block({
Height: BlockHeight,
BlockSize: 1,
blockHeader: {
version: 1,
prevBlockHash: "00000",
timestamp: timestamp,
bits: bits,
nonce: blockHeader.nonce,
blockHash: blockHeader.blockhash,
},
TxCount: 1,
Transactions: Transaction,
});
// Mongoose Schema, Write data
BlockObj.save((err) => {
if (err) return console.log(`Error while Writing the Block ${err}`);
console.log(`Block Written Successfully!!!!!!!`);
});
this.chain = new block.Block(BlockHeight, 1, blockHeader, 1, Transaction);
console.log(BlockObj);
}
// Main Function to trigger the process
main() {
this.chain = "";
this.GenesisBlock();
while (true) {
let lastBlock = this.chain;
let Blockheight = lastBlock.Height + 1;
let prevBlockHash = lastBlock.BlockHeader.blockhash;
this.addBlock(Blockheight, prevBlockHash);
}
}
}
mongoose.connection.once("open", async () => {
console.log("Connection Verified and ready to write data");
// Create an instance and call the main method
const blockchain = new Blockchain();
blockchain.main();
});
Issue was due to async/await. Here is the updated code that works.
require("dotenv").config();
const { hash256 } = require("../util/util");
const block = require("./block");
const blockchain = require("./blockHeader");
const Block = require("../database/model/blockSchema");
const connect = require("../database/dbtest");
const getLastBlock = require("../database/read");
VERSION = 1;
const ZERO_HASH = String("0").padStart(64, "0");
let mongoose = "";
class Blockchain {
async GenesisBlock() {
try {
console.log(mongoose.connection.readyState);
const BlockHeight = 0;
const prevBlockHash = ZERO_HASH;
await this.addBlock(BlockHeight, prevBlockHash);
} catch (err) {
console.log(`Error in Genesis Blockchain Function \n ${err}`);
}
}
async addBlock(BlockHeight, prevBlockHash) {
let timestamp = Date.now();
let Transaction = `Codies Alert sent ${BlockHeight} to Anni Maan`;
let merkleRoot = hash256(Transaction);
let bits = "ffff001f";
let blockHeader = new blockchain.BlockHeader(
VERSION,
prevBlockHash,
merkleRoot,
timestamp,
bits
);
blockHeader.mine();
let BlockObj = {
Height: BlockHeight,
BlockSize: 1,
blockHeader: {
version: 1,
prevBlockHash: blockHeader.prevBlockhash,
merkleroot: merkleRoot,
timestamp: timestamp,
bits: bits,
nonce: blockHeader.nonce,
blockhash: blockHeader.blockhash,
},
TxCount: 1,
Transactions: Transaction,
};
// Mongoose Schema, Write data
try {
await new Block(BlockObj).save();
console.log(BlockObj);
console.log("Block Written Successfully");
this.chain = new block.Block(BlockHeight, 1, blockHeader, 1, Transaction);
} catch (err) {
console.log(`Error in addBlock Function \n ${err}`);
}
}
// Main Function to trigger the process
async main() {
const lastBlock = await getLastBlock.main(true);
console.log(lastBlock[0]);
this.chain = lastBlock[0];
if (!this.chain) {
await this.GenesisBlock();
}
while (true) {
console.log(mongoose.connection.readyState);
let lastBlock = this.chain;
let Blockheight = lastBlock.Height + 1;
let prevBlockHash = lastBlock.blockHeader.blockhash;
await this.addBlock(Blockheight, prevBlockHash);
}
}
}
const createConnection = async () => {
try {
mongoose = await connect();
const blockchain = new Blockchain();
blockchain.main();
} catch (err) {
console.log("Error while con", err);
}
};
createConnection();
The issue in your code is due to the asynchronous programming, whenever you make a db call it is an asynchronous request and you will need to use async-await or Promises to make it work. In your previous code you haven't used async await thats why your data is not getting written into the db.
You can learn about async await here link and about promises here.
Please go through it, promises are the core concept of js and you will definitely need it if you are using node js.
Also try to learn about synchronous and asynchronous from here, these are really necessary and base of node js.
All these db calls needs to call with promises or async await to make it work.

How to call a function directly through cmd to fetch and update records into database through Node js

I have a file CreateNewUserID.js, which has the code as below.
const Connection = require('./database/Connection')
const createNewUserID = async(connData, userId) => {
try{
var getConn = await Connection.get().getConn();
const query = `exec BaseDB.get_client_info`
var clientusers = await getConn.query(query);
var getConn1 = await Connection.get().getConnection(connData)
var res = await getConn1.execute('BaseDB.get_all_existing_users');
res.recordsets[1].map(async (val) => {
try{
var newid = val.id+'NEWID';
var getConn2 = await Connection.get().getConnection(connData)
getConn2.input('userid', userid)
getConn2.input('updatedid', newid)
var res2 = await getConn2.execute(`BaseDB.update_users_with_newid`)
} catch (err) {
console.log(err)
return { err, message: 'First DB Connection' }
}
})
} catch (err) {
console.log(err)
return { err, message: 'Second DB Connection' }
}
}
const connData = {
"clientuserid": "12345"
}
createNewUserID(connData)
Also I have a Connection.js where I have made DB connection configurations of Base Database and client DB.The client DB Database will be dynamic. So, for now I am passing the DB name through constant connData. I have defined connData in the same file above in CreateNewUserID.js.
My Connection.js is below:
const sql = require('mssql')
class Connection {
// CONNECTION CONFIGURATION OF CLIENT DB
getConnection = async (conData) => {
const connData = JSON.parse(conData)
try {
// sql.close();
const config = {
user: process.env.SQL_USER,
password: process.env.SQL_PASSWORD,
server: process.env.SQL_SERVER,
database: connData.clientuserid
}
const pool = await new sql.ConnectionPool(config)
const req=await pool.connect()
const conn = await req.request()
// const req = await sql.connect(config)
// const conn = await req.request()
return conn;
} catch (err) {
return err;
}
};
// CONNECTION CONFIGURATION OF BASE DB
getConn = async () => {
try {
// sql.close();
const config = {
user: process.env.SQL_USER,
password: process.env.SQL_PASSWORD,
server: process.env.SQL_SERVER,
database: process.env.SQL_DATABASE
}
const pool = await new sql.ConnectionPool(config)
const req=await pool.connect()
const conn = await req.request()
// const req = await sql.connect(config)
// const conn = await req.request()
return conn;
} catch (err) {
return err;
}
};
}
Connection.__instance = null;
Connection.get = () => {
if (!Connection.__instance) {
Connection.__instance = new Connection();
}
return Connection.__instance;
};
module.exports = Connection;
When I try to run the file through CMD with command node CreateNewUserID.js I am getting the error as unexpected token 0 in json at position 1 at first catch with message "First DB connection".
Why am I getting the error and how to resolve it. Please help. Thanks in advance

Reusing SQL server Database Connections With Azure Functions Using Javascript

I cannot find clear information on how to manage SQL server database connections from an Azure function written in Javascript.
I am using a connection pool code -
const pool = new sql.ConnectionPool(config);
const poolConnect = pool.connect();
pool.on('error', err => {
// ... error handler
})
and I am using the poolConnect object from the function which is executing the query
export const selectQuery = function() {
const connectionPool = await mssqlDBPoolConnect;
const request = connectionPool.request();
await request.query('select query');
}
So how can I use the same connection pool across all azure functions.
Create two folder named config and toolkit under your root path. Put your db.js in config folder, and create a sql helper class to export a function named sqltools.js in toolkit folder.
So you could use the same connection pool by calling sqltools in your function's code. This step help you to reduce using the same code in every function.
Try use the db.js code below:
const sql = require('mssql')
const config = {
user: 'yourusername',
password: 'yourpassword',
server: 'yoursqlserver.database.windows.net', // You can use 'localhost\\instance' to connect to named instance. Do not use TCP.
database: 'yourdb',
"options": {
"encrypt": true,
"enableArithAbort": true
}
}
const poolPromise = new sql.ConnectionPool(config)
.connect()
.then(pool => {
console.log('Connected to MSSQL')
return pool
})
.catch(err => console.log('Database Connection Failed! Bad Config: ', err))
module.exports = {
sql, poolPromise
}
The sqltools.js class:
const { poolPromise } = require('../config/db')
module.exports.sqltools = {
ExecSqlQuery : async function(arg){
const pool = await poolPromise
//SELECT *FROM SYSOBJECTS WHERE xtype = \'U\'
var result=null;
try {
result = await pool.request()
.query(arg)
} catch (error) {
console.log(error.message);
}
return result;
},
ExecProce : function (arg2, arg3, arg4){
console.log(arg2,arg3,arg4);
}
}
Here is my HttpTrigger1 index.js code, call ExecSqlQuery to exec sqlstrings:
const { sqltools } = require('../toolkit/sqltools');
module.exports = async function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
var result=null;
try {
// call ExecSqlQuery func
result = await sqltools.ExecSqlQuery('SELECT *FROM SYSOBJECTS WHERE xtype = \'U\'');
} catch (error) {
console.log(error.message);
}
const responseMessage ="Func 1 Result : TableName= " + result.recordset[0].name;
context.res = {
// status: 200, /* Defaults to 200 */
body: responseMessage
};
}

node.js async/await using with MySQL

I need to get all results synchronized and append to a string with async/await keywords like c#.
I am new to node.js and I can not adapt this new syntax to my code.
var string1 = '';
var string2 = '';
var string3 = '';
var string4 = '';
DatabasePool.getConnection(function(err, connection) {
connection.query(query,function (err, result) {
if (err){};
string1 = result;
});
connection.query(query,function (err, result) {
if (err){};
string2 = result;
});
connection.query(query,function (err, result) {
if (err){};
string3 = result;
});
connection.query(query,function (err, result) {
if (err){};
string4 = result;
});
//I need to append all these strings to appended_text but
//all variables remain blank because below code runs first.
var appended_text = string1 + string2 + string3 + string4;
});
if you happen to be in Node 8+, you can leverage the native util.promisify() with the node mysql.
Do not forget to call it with bind() so the this will not mess up:
const mysql = require('mysql'); // or use import if you use TS
const util = require('util');
const conn = mysql.createConnection({yourHOST/USER/PW/DB});
// node native promisify
const query = util.promisify(conn.query).bind(conn);
(async () => {
try {
const rows = await query('select count(*) as count from file_managed');
console.log(rows);
} finally {
conn.end();
}
})()
Use mysql2 packet. It has promise wrapper so you can do that:
async function example1 () {
const mysql = require('mysql2/promise');
const conn = await mysql.createConnection({ database: test });
let [rows, fields] = await conn.execute('select ?+? as sum', [2, 2]);
}
Assuming that your ORM that you are using it promise-based you can do something like this
async function buildString() {
try {
const connection = await DatabasePool.getConnection();
const string1 = await connection.query(query);
const string2 = await connection.query(query);
const string3 = await connection.query(query);
const string4 = await connection.query(query);
return string1 + string2 + string3 + string4;
} catch (err) {
// do something
}
}
Any promise can be used with async/await by putting await in front of the call. However, notice that this function must be used within an async function "wrapper". You need to handle the errors in try/catch blocks.
I also want to point out that these 4 queries are not run simulatneously. You'll still need to use Promise.all for that.
If you want to use mysql (also called mysqljs) you have to do a little bit of work if you don't want to use a wrapper. But it's easy enough. Here is how the connect function would look like:
const mysql = require('mysql')
var my_connection = mysql.createConnection({ ... })
async function connect()
{
try
{
await new Promise((resolve, reject) => {
my_connection.connect(err => {
return err ? reject(err) : resolve()
})
})
}
catch(err)
{
...handle errors...
}
}
connect()
As you can see the await will know how to handle a promise. You create such and use the resolve/reject functions in the callback implementation. That's all there is to it, really, so using a wrapper may be a bit much unless you access your database a lot.
As stated by LeOn - Han Li, i include small modifications, since I had to work with the result.
var mysql = require('mysql');
const util = require('util');
const conn = mysql.createConnection({
host : '127.0.0.1',
user : 'user',
password : 'password',
database : 'database'
});
const query = util.promisify(conn.query).bind(conn);
let result = async function() {
var userCourse = [];
try {
const rows = await query('select * as count from file_managed');
} finally {
conn.end();
return userCourse;
}
};
result()
.then(value => {
console.log(value)
});
Or use mysql-async-simple
https://www.npmjs.com/package/mysql-async-simple
const { makeDb } = require('mysql-async-simple');
const mysql = require("mysql");
const connection = mysql.createConnection({
host: process.env.HOST,
user: process.env.USER,
password: process.env.PASSWORD,
database: process.env.DB
});
const db = makeDb();
await db.connect(connection);
try {
const users = await db.query(connection, 'SELECT * FROM users');
} catch (e) {
// handle exception
} finally {
await db.close(connection);
}
You can use the promise-mysql package like so:
const mysql = require('promise-mysql')
const getDbConnection = async () => {
return await mysql.createConnection({
host: process.env.HOST,
user: process.env.USER,
password: process.env.PASSWORD,
database: process.env.DB
})
}
const getUsers = async () => {
const db = await getDbConnection()
const users = await db.query("SELECT * FROM users")
await db.end()
return users
}
You would have to make sure that the mysql library you are using either supports Promises, which are required by async/await, or use a tool like Bluebird's promisifyAll to wrap the library.
async function appendedText() {
const connection = await DatabasePool.getConnectionAsync();
const [string1, string2, string3, string4] = await [
connection.query(query1),
connection.query(query2),
connection.query(query3),
connection.query(query4),
];
return string1 + string2 + string3 + string4;
}
Note that calling appendedText() will actually return a Promise and not a value.
appendedText().then(appended_text => {});
It seems you use mysqljs which isn't a promised based library. So you can't achieve what you want using this library. So what you can do is use a promised based library like Sequelize or else as a comment suggests:
use a tool like Bluebird's promisifyAll to wrap the library.
I don't know much about wrapping thing, so what I did was to switch to the sequelize.
Instead of using util or promise/mysql we can implement promise inside mysql.connect
var con = require('mysql');
var mysql = con.createConnection({
host: "localhost",
user: "root",
password: "pass",
database: "test"
});
async function asyncAwait(req, res) {
var promise1;
mysql.connect((err) => {
promise1 = new Promise((resolve, reject) => {
console.log('Mysql: Connected');
resolve(response.write(uc.upperCase('Connected\n')));
});
promise1
.then(() => {
//Implement the logic here
})
.catch(error => {
console.log(error)
});
})
}
await asyncAwait();
const { makeDb } = require('mysql-async-simple');
const mysql = require("mysql");
const connection = mysql.createConnection({
host: process.env.HOST,
user: process.env.USER,
password: process.env.PASSWORD,
database: process.env.DB
});
const db = makeDb();
await db.connect(connection);
try {
const users = await db.query(connection, 'SELECT * FROM users');
} catch (e) {
// handle exception
} finally {
await db.close(connection);
}

Categories

Resources