NodeJS - 'database.getOneWhere' is not a function - javascript

I'm trying to make global database functions, but everytime I try to access them it always says that the object is undefined, and I can't figure out why.
controllers/api/v1/users/index.js:
'use strict';
var path = require('path');
var database = require(path.resolve('database'));
module.exports = function (router) {
router.put('/', function (req, res) {
database.getOneWhere('table', 'row', 'data').then(result => {
//
});
});
}
database/index.js:
'use strict';
const r = require('rethinkdb');
module.exports = async function() {
getOneWhere = async function(table, key, value, callback) {
let conn = await r.connect({host: '127.0.0.1', port: 28015});
let cursor = await r.db('table').table(table).filter(r.row(key).eq(value)).run(conn);
try {
let arr = await cursor.toArray();
callback(arr);
} catch(e) {
callback(e);
}
}
}
It always says that database.getOneWhere is not a function. Any idea how to fix this?

getOneWhere should be a property of module.exports. You defined module.exports as a function and put getOneWhere within that though. It should be:
'use strict';
const r = require('rethinkdb');
module.exports = {
getOneWhere: async function(table, key, value, callback) {
let conn = await r.connect({host: '127.0.0.1', port: 28015});
let cursor = await r.db('table').table(table).filter(r.row(key).eq(value)).run(conn);
try {
let arr = await cursor.toArray();
callback(arr);
} catch(e) {
callback(e);
}
}
};
Or alternatively:
'use strict';
const r = require('rethinkdb');
module.exports.getOneWhere = async function(table, key, value, callback) {
let conn = await r.connect({host: '127.0.0.1', port: 28015});
let cursor = await r.db('table').table(table).filter(r.row(key).eq(value)).run(conn);
try {
let arr = await cursor.toArray();
callback(arr);
} catch(e) {
callback(e);
}
};

Related

mock dynamodb partiql using jest

I didn't find a way to mock the new feature of dynamodb "PartiQL" defined in a lambda function.
In PartiQL we can use executeStatement to run sql like queries which are a kind of DynamoDBCustomizations.
But he configuration below return an error:
UnrecognizedClientException: The security token included in the
request is invalid
which means that the configuration of jest-mock is not correct.
This is the code to be tested
'use strict';
var ddb = new AWS.DynamoDB({ apiVersion: '2012-08-10' });
const TABLE_NAME = process.env.TABLE_NAME;
async function queryTest() {
let params = {
Statement: `select * from ${TABLE_NAME}`
};
let statementResult = await ddb.executeStatement(params).promise();
return statementResult.Items;
}
module.exports.get = async (event) => {
var result = queryTest();
if (!result) {
return {
statusCode: 200,
body: JSON.stringify(result)
};
}
else {
return {
statusCode: 400,
body: JSON.stringify(result)
};
}
};
and the testing script:
'use strict';
const AWS = require('aws-sdk');
const jestPlugin = require('serverless-jest-plugin');
const lambdaWrapper = jestPlugin.lambdaWrapper;
const mod = require('./handler');
function mock_aws() {
let mockDynamoDBClient = {
executeStatement: {
promise: jest.fn()
},
promise: jest.fn(),
};
jest.mock("aws-sdk", () => {
const config = {
update: jest.fn(),
};
return {
DynamoDB: jest.fn().mockImplementation(() => {
return {
executeStatement: () => mockDynamoDBClient.executeStatement,
};
}),
config: config
};
});
return mockDynamoDBClient;
}
describe('test', () => {
const OLD_ENV = process.env;
var mDynamoDb;
var wrapped;
beforeAll(async () => {
jest.resetModules();
wrapped = await lambdaWrapper.wrap(mod, { handler: 'get' });
process.env = { ...OLD_ENV };
process.env.TABLE_NAME = "TEST";
mDynamoDb = mock_aws();
});
test('implement tests here', async (done) => {
const mResult = [{ 'TEST': 1 }] ;
const response = await wrapped.run({})
expect(response).toEqual({
"statusCode": 200,
"body": JSON.stringify(mResult)
});
done();
});
});

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

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

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

How to execute those 2 code snippets asynchronously/parallell

I am beginner at javascript so please bear with me. I wonder how to put async() event in the right way.
I have 2 code snippets that I want to execute asynchronously and not synchronously. The code snippets use a library that do HTTP requests so that is out of my control.
So I like the 2 code snippets to execute in parallell somehow. What I have are those 2 code snippets and I also think I understand that I only want to declare the first 2 lines once as those lines takes time:
'use strict';
const ccxt = require ('ccxt');
The 2 code snippets are the below
Code snippet1:
'use strict';
const ccxt = require ('ccxt');
(async () => {
try{
const exchange = new ccxt.one({ enableRateLimit: true })
const tickers = await exchange.fetchTickers()
const obj = { tickers }
const fs = require('fs');
fs.writeFile("/myproject/file1.txt", JSON.stringify(obj), function(err) { });
}catch{}
}) ()
Code snippet2:
'use strict';
const ccxt = require ('ccxt');
(async () => {
try{
const exchange = new ccxt.two({ enableRateLimit: true })
const tickers = await exchange.fetchTickers()
const obj = { tickers }
const fs = require('fs');
fs.writeFile("/myproject/file2.txt", JSON.stringify(obj), function(err) { });
}catch{}
}) ()
I tried this code and it actually did it in parallell. It executed very fast.
If you have any idéas of code to add to make it even more efficient I would be very happy to hear how to do that. (For example open up more ports or any other bottlenecks?)
'use strict';
const ccxt = require ('ccxt');
(async () => {
try{
const exchange = new ccxt.one({ enableRateLimit: true })
const tickers = await exchange.fetchTickers()
const obj = { tickers }
const fs = require('fs');
fs.writeFile("/myproject/file1.txt", JSON.stringify(obj), function(err) { });
}catch{}
}) ();
(async () => {
try{
const exchange = new ccxt.two({ enableRateLimit: true })
const tickers = await exchange.fetchTickers()
const obj = { tickers }
const fs = require('fs');
fs.writeFile("/myproject/file2.txt", JSON.stringify(obj), function(err) { });
}catch{}
}) ();
Use Promise.all:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
'use strict';
const ccxt = require ('ccxt')
const fs = require('fs')
async function work (exchangeId) {
try {
const exchange = new ccxt[exchangeId] ({ enableRateLimit: true })
const tickers = await exchange.fetchTickers ()
const obj = { tickers }
const filename = exchangeId + '.txt'
fs.writeFileSync (filename, JSON.stringify (obj))
console.log ('saved', filename)
} catch {
}
}
(async () => {
const exchangeIds = [ 'bittrex', 'bitfinex' ]
await Promise.all (exchangeIds.map (exchangeId => work (exchangeId)))
}) ()
It's not clear to me what you want to happen but your code will not catch all errors as written. I know you seemed to be ignoring all errors but just in case, ...
If you're going to use async/await then you should go all in. That means you should use fs.promises.readFile not fs.readFile. Either that or you should wrap fs.readFile in a promise either manually or using util.promisify.
So the code becomes
'use strict';
const ccxt = require ('ccxt');
const thing1 = (async () => {
try{
const exchange = new ccxt.one({ enableRateLimit: true })
const tickers = await exchange.fetchTickers()
const obj = { tickers }
const fs = require('fs');
await fs.promises.writeFile("/myproject/file1.txt", JSON.stringify(obj));
} catch {
// catch error here
}
}) ();
const thing2 = (async () => {
try{
const exchange = new ccxt.two({ enableRateLimit: true })
const tickers = await exchange.fetchTickers()
const obj = { tickers }
const fs = require('fs');
await fs.promises.writeFile("/myproject/file2.txt", JSON.stringify(obj));
} catch {
// catch error here
}
}) ();
If wanted to do both to wait for both things then you could use Promise.all by passing in an array that contain each of the promises returned by both async functions.
'use strict';
const ccxt = require ('ccxt');
const thing1 = (async () => {
try{
const exchange = new ccxt.one({ enableRateLimit: true })
const tickers = await exchange.fetchTickers()
const obj = { tickers }
const fs = require('fs');
await fs.promises.writeFile("/myproject/file1.txt", JSON.stringify(obj));
} catch {
// catch error here
}
}) ();
const thing2 = (async () => {
try{
const exchange = new ccxt.two({ enableRateLimit: true })
const tickers = await exchange.fetchTickers()
const obj = { tickers }
const fs = require('fs');
await fs.promises.writeFile("/myproject/file2.txt", JSON.stringify(obj));
} catch {
// catch error here
}
}) ();
(async() => {
await Promise.all([thing1, thing2]);
// do something after thing1 and thing2
}) ();
And of course at given the 2 functions are the same except for the filename then
'use strict';
const ccxt = require ('ccxt');
async function fetchTickersAndWrite({method, filename}) {
try{
const exchange = new ccxt[method]({ enableRateLimit: true })
const tickers = await exchange.fetchTickers()
const obj = { tickers }
const fs = require('fs');
await fs.promises.writeFile(filename, JSON.stringify(obj));
} catch {
// catch error here
}
}
(async() => {
await Promise.all([
{ method: 'one', filename: `/myproject/file1.txt` },
{ method: 'two', filename: `/myproject/file2.txt` },
].map(fetchTickersAndWrite));
// do something
}) ();

"x" is not a constructor

I'm trying to get a result from Sql query.
I have the following class which should execute the Sql connection and query:
'use strict';
//db.js
const sql = require('mssql');
require('dotenv').config();
var utils = function(){
var config = {
server: 'sql01',
database: 'db123',
options: {
instanceName: 'in1',
encrypt: true
}
};
module.exports = {
/** Define sql queries here */
GetEmpName(id) {
let my_query = `Select filed1 FROM db123 WHERE id='${id}'`;
sql.connect(config).then(function () {
new sql.Request()
.query(my_query).then(function (recordset) {}).catch(function (err) {
console.log(err);
});
});
}
};
};
And that's the main page:
'use strict;'
let HomePage = require('../page/home_page.js');
let utilsPage = require('../utils/utils.js');
describe("login to website",function(){
let employeeId;
let employeeBday;
let home = new HomePage();
//let utils = new utilsPage();
it('get an employee's Id', function (done) {
utilsPage.GetEmpName('100001387');
done();
})
});
I'm getting an error says: utilsPage is not a constructor.
What am I doing wrong?
In Node.js there are two ways of exporting and accessing function variables. One is by creating a global function and putting all your functions, variables into that and export that module as a whole by using module.exports.
Another way is just exporting the function by exports and then accessing that in your specific file. So in your case you could do it in either of the below 2 ways-
1st Approach: Using your Utils function globally -
'use strict';
//db.js
const sql = require('mssql');
require('dotenv').config();
var utils = function(){
this.config = {
server: 'sql01',
database: 'db123',
options: {
instanceName: 'in1',
encrypt: true
}
};
/** Define sql queries here */
this.getEmpName = function(id) {
let my_query = `Select filed1 FROM db123 WHERE id='${id}'`;
sql.connect(config).then(function () {
new sql.Request()
.query(my_query).then(function (recordset) {}).catch(function (err) {
console.log(err);
});
});
}
};
module.exports = new utils();
You could use it the same way as you have used -
'use strict;'
let HomePage = require('../page/home_page.js');
let utilsPage = require('../utils/utils.js');
describe("login to website",function(){
let employeeId;
let employeeBday;
let home = new HomePage();
it('get an employee's Id', function (done) {
utilsPage.getEmpName('100001387');
done();
})
});
2nd Approach: Exporting only the getEmpName function -
'use strict';
//db.js
const sql = require('mssql');
require('dotenv').config();
var config = {
server: 'sql01',
database: 'db123',
options: {
instanceName: 'in1',
encrypt: true
}
};
/** Define sql queries here */
exports.getEmpName = function(id) {
let my_query = `Select filed1 FROM db123 WHERE id='${id}'`;
sql.connect(config).then(function () {
new sql.Request()
.query(my_query).then(function (recordset) {}).catch(function (err) {
console.log(err);
});
});
}
You would use it the same as well:
'use strict;'
let HomePage = require('../page/home_page.js');
let utilsPage = require('../utils/utils.js');
describe("login to website",function(){
let employeeId;
let employeeBday;
let home = new HomePage();
it('get an employee's Id', function (done) {
utilsPage.getEmpName('100001387');
done();
})
In your utils.js file you shouldn't wrap your code in the utils function
'use strict';
//db.js
const sql = require('mssql');
require('dotenv').config();
var config = {
server: 'sql01',
database: 'db123',
options: {
instanceName: 'in1',
encrypt: true
}
};
module.exports = {
/** Define sql queries here */
GetEmpName(id) {
let my_query = `Select filed1 FROM db123 WHERE id='${id}'`;
sql.connect(config).then(function () {
new sql.Request()
.query(my_query).then(function (recordset) { }).catch(function (err) {
console.log(err);
});
});
}
};
In your main page file you can access your exported module like this
utilsPage.GetEmpName('100001387')
There's no need to call new utilsPage(). In order to use the keyword new you must either export a class or a constructor function.

Categories

Resources