How to create a async function and export it? - node.js

Using node + express. I want to create a module that use several querys.
how can I export this asynchronous function to app.js?
This is the function that im trying to make it work:
app.js (where io are socketio instance)
const users = require('./sockets/users')(io)
users.js
const Users = require('../models/Users.model')
const users = async function(client){
client.on('connection', socket =>{
socket.on('userAdd',(data) =>{
console.log(data);
})
const users = await Users.find()
console.log(users[0]);
})
}
module.exports = users
Error: SyntaxError: await is only valid in async function

First create two files. you can create functions into one and can export it and in another file you can import that functions. check the code below.
> server.js
const addition = require('./addition.js') // path to your another file
const result = addition.add(5, 8) // calling function of another file
console.log(result)
another file
> addition.js
const add = (x, y) => x + y;
module.exports = { add } // export this function
output:
13

I was typing the async keyword in the incorrect function. Its in the connection function
const Users = require('../models/Users.model')
const users = function(client){
client.on('connection', async socket =>{
socket.on('userAdd',(data) =>{
console.log(data);
})
const users = await Users.find()
console.log(users[0]); //user 1
})
}
module.exports = users

You can try to use a class for that and export that class and use it

Related

Send message to channel in a function

I have an event handler for the ready event.
ready.js:
const { Events } = require('discord.js');
const db = require("../config/database");
const itemdb = require("../config/itemdb");
const items = require("../models/items");
const AHItems = require('../models/ahitems.js');
const RSS = require('../models/regionserversettings.js');
module.exports = {
name: Events.ClientReady,
once: true,
execute(client) {
console.log(`Ready! Logged in as ${client.user.tag}`);
db.authenticate()
.then(() => {
console.log('Logged in to DB!');
AHItems.init(db);
AHItems.sync();
RSS.init(db);
RSS.sync();
})
.catch(err => console.log(err));
itemdb.authenticate()
.then(() => {
console.log('Logged in to Item DB!');
items.init(itemdb);
items.sync();
})
.catch(err => console.log(err));
},
};
From inside the execute block I can use client.channels.cache.get('xxxxxx').send('Hello');
I want to use the send method in another File:
const AHItems = require("../models/ahitems");
const RSS = require("../models/regionserversettings");
const getprice = require("../api/getcurrentPrice");
const client = require("../events/ready");
const pricealarm = async function()
{
let ahitems = await AHItems.findAll({attributes: ['guildID', 'itemID']});
for (let i = 0; i < ahitems.length; i++) {
const guild = ahitems[i].dataValues.guildID;
const RSSData = await RSS.findOne({where: {guildID: guild}});
const item = ahitems[i].dataValues.itemID;
const access_token = RSSData.AccessToken;
const server = RSSData.serverID;
const price = await getprice(access_token, item, server);
const channel = client.channels.cache.get('x').send('test');
console.log(channel);
}
}
module.exports = pricealarm;
But if I try to do this, it tells me 'Unresolved function or method send()'
I think I am requiring the wrong file, but am unsure, which one I have to require
The issue with your code is that you are trying to use the send() method from an object client that has not been properly instantiated in the file where you want to use it. In your ready.js file, you correctly initialize the client object and can use its send() method inside the execute block.
However, in the other file where you want to use the send() method, you import the ready.js file, but you are only importing the module, not the instantiated client object. Therefore, the send() method is unresolved and cannot be called.
To fix this issue, you need to modify the ready.js file to export the client object in addition to the module.exports statement. For example, you can add the following line at the end of the execute block:
module.exports.client = client;
Then, in your other file, you can import the client object by requiring the ready.js file and accessing the client property of the exported module. For example:
const ready = require("../events/ready");
const client = ready.client;
// Now you can use client.channels.cache.get('xxxxxx').send('Hello');
With these modifications, you should be able to properly use the send() method from the client object in both files.

sinon stub calls fake calling actual function

I'm having situation where I want to write unit test cases for a function to make sure if it is working fine or not. So I have created stub for that specific function and when I tries to calls fake that stub, the function is actually getting called instead of fake call. Below is my scenario:
I have an main function from where I'm calling the function saveData(**).
saveData(**) function is calling AWS SQS to save an message to DB
Below is my main function:
'use strict';
async function mainFunction() {
try {
await saveData(
name,
age,
);
return true;
} catch (e) {
console.log('Error - [%s]', e);
return null;
}
}
module.exports = { mainFunction };
Below is my saveData(**) function:
'use strict';
const AWS = require('aws-sdk');
const sqs = new AWS.SQS();
const saveData = async (
name,
age,
) => {
await sendMessage(JSON.stringify(dbData));
const params = {
DelaySeconds: <some_delay>,
MessageAttributes: <messageAttributes>,
MessageBody: {name:name, age:age},
QueueUrl: <URL_FOR_QUEUE>,
};
return sqs.sendMessage(params).promise();
return true;
};
module.exports = {
saveData,
};
And my test case is,
'use strict';
const express = require('express');
const bodyParser = require('body-parser');
require('app-module-path').addPath('./src');
const sinon = require('sinon');
const app = express();
const sqsSender = require('lib/queue');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const main = require('../../../src/main-function');
const routes = require('routes');
routes.configure(app);
let mainFunctionStub;
let saveDataStub;
describe('/v1/main', () => {
beforeEach(() => {
mainFunctionStub = sinon.stub(main, 'mainFunction');
saveDataStub = sinon.stub(sqsSender, 'saveData');
});
describe('Test', () => {
it(`should return success`, (done) => {
const name = 'Name';
const age = 'Age';
saveDataStub.resolves({
name,
age,
});
});
});
afterEach(() => {
mainFunctionStub.restore();
mainFunctionStub.reset();
saveDataStub.restore();
saveDataStub.reset();
});
});
But this test is returning,
error: Jun-20-2021 20:07:05: Error - [Error [ConfigError]: Missing region in config
and,
Error: Timeout of 3500ms exceeded.
From this error I can say that this is actually calling SQS function instead of faking. How can I resolve this or how can I fake call to this function? I'm new to this unit testing so any help would be appriciated.
Stubbing works by replacing the property on the exports object. Since the require happens before sinon replaces the function, you capture the reference to the original function instead of dynamically using the currently set one.
You haven't showed your require calls in the main file, but from the call-site I infer you're importing it like const { saveData } = require('../foo/sqsSender'). This means you're grabbing the function off of the object when first loading the code. If you instead keep a reference to the sqsSender module instead, and reference the function on invocation, the stub should work.
'use strict';
// Don't destructure / grab the function.
const sqsSender = require("../foo/sqsSender")+
async function mainFunction() {
try {
// Use reference through module
await sqsSender.saveData(
name,
age,
);
return true;
} catch (e) {
console.log('Error - [%s]', e);
return null;
}
}
module.exports = { mainFunction };

async/await not working with mongoose instance methods

I'm try to create user mongoose document which require a storage path. I want to await for directory to be created and path resolved. But it is not working and after user is saved, user.storagePath is still undefined. please figure out problem.
Following is code of createStorage()
const getMountRoot = require('../configuration/configuration').getMountRoot
const path = require('path')
const fs = require('fs')
const Logger = require('../configuration/configuration').getLogger
module.exports = (email, firstName, secondName) => {
email = String(email).toLowerCase().replace(/[#_\.\-]/g, '')
firstName = String(firstName).toLowerCase().replace(/[#_\.\-]/g, '')
secondName = String(secondName).toLowerCase().replace(/[#_\.\-]/g, '')
let storagePath = path.join(getMountRoot(), `${secondName}${email}${firstName}`)
return fs.promises.mkdir(storagePath, { recursive: true })
.then(() => { return storagePath })
.catch(() => {Logger.log(err); return storagePath})
}
And following is instance method
const createStorage = require('../extra/create-storage')
userSchema.methods.createStorage = async function() {
this.storagePath = await createStorage(this.email, this.firstName, this.secondName)
}
Kindly note that I call createStorage() on User instance before calling the save()
As #qqilihq figured, I need to await at instance method call. Doing that worked correctly.

Problem using function in exported custom module in nodejs

I am new to nodejs and I am trying to export my custom module but it says function is not defined or is not a function.
I have created a module which contains a function to validate the request body using Joi library. Below is what I have done
validator.js
const Joi = require('joi');
var validateCustomer = function(customer) {
const schema = {
name: Joi.string().min(3).required()
}
return Joi.validate(customer, schema)
}
module.exports.validator = validateCustomer;
customers.js
const validator = require('../myModules/validator');
router.post('/', async (req, res) => {
const {error} = validator(req.body);
if(error) return res.error(404).send(error.details[0].message);
...some code
});
Please help
Change out
module.exports.validator = validateCustomer;
for
module.exports = validateCustomer
in validator.js.

TypeError: contract.test is not a function tronweb nodejs

I am trying to access Tron smart contract which is deployed on the Shasta test network using Tron-Web. I am using node-casiko server Following is my code:
const TronWeb = require('tronweb')
// This provider is optional, you can just use a url for the nodes instead
const HttpProvider = TronWeb.providers.HttpProvider;
const fullNode = 'https://api.shasta.trongrid.io';
const solidityNode = 'https://api.shasta.trongrid.io';
const eventServer = 'https://api.shasta.trongrid.io';
const privateKey = 'my test account private key';
const tronWeb = new TronWeb(
fullNode,
solidityNode,
eventServer,
privateKey
);
module.exports = {
tmp: async function (req, res, next){
try{
var contract = await tronWeb.trx.getContract("TS71i14jzLawbtu4qPDKEsFERSp6CQb93948");
//res.send(contract)
var result = await contract.test().call();
//res.send(result);
}
catch(err){
console.error(err)
}
}
}
When I execute this js file using node having version v10.15.3. I am getting Error as:
TypeError: contract.test is not a function
at tmp (/home/administrator/node-Casiko/models/tronContract.js:25:32)
at process._tickCallback (internal/process/next_tick.js:68:7)
If I print the contract variable it is printing all information about the contract, but it is not calling the contract methods. Can somebody help me with this problem?
Well, I managed to find an answer for self-question. Just change the code as below. It works!!
module.exports = {
tmp: async function (req, res, next){
try{
var contract = await tronWeb.contract()
.at("TS71i14jzLawbtu4qPDKEsFERSp6CQb93948")
var result = await contract.test().call();
}
catch(err){
console.error(err)
}
}

Resources