fastify is undefined in model - node.js

I'm trying fastify with fastify-bookshelfjs.
contact (model)
module.exports = async function (fastify) {
console.log("4")
fastify.bookshelf.Model.extend({
tableName: 'contacts',
})
}
contact (controller)
console.log("3")
const Contact = require('../models/contact')()
// Get all contact
async function getContact(req, reply) {
const contacts = Contact.fetchAll()
reply.code(200).send(contacts)
}
module.exports = getContact
contact (routes)
module.exports = async function (fastify) {
console.log("2")
const contact = require('../controller/contact')
fastify.get('/', contact.getContact)
}
When the server start I get this output
2
3
4
(node:10939) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'bookshelf' of undefined
1
server listening on 3000
Why fastify in contact(model) is undefined and how can fix ?

In your controller, when you import the model, you need to put fastify as argument.
Also, you have to import the fastify module.
Your contact (controller) should be
const fastify = require('fastify') // import the fastify module here
console.log("3")
const Contact = require('../models/contact')(fastify)
// Get all contact
async function getContact(req, reply) {
const contacts = Contact.fetchAll()
reply.code(200).send(contacts)
}
module.exports = getContact

Related

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 };

Why the object is not passed within the callback of the route handler of express.Router(), being exported from different module?

Entrypoint of my server is publisher.js. Its code is the following:
'use strict';
const publishingRoute = require('./routes/enqueue');
. . . .
. . . .
const PublishingServicePort = process.env.PUB_PORT || 4001;
const RabbitMQHostURL = process.env.RABBITMQ_AMQP_URL;
const RabbitMQQueueName = process.env.QUEUE;
const RabbitMQRoutingKey = process.env.ROUTING_KEY;
const RabbitMQExchange = process.env.EXCHANGE;
let rbmqChannel;
let rbmqConnection;
const app = express();
app.use(bodyParser.json());
//initConnection() creates the TCP connection and confirm channel with the Broker. No error here
(async function initConnection() {
rbmqConnection = await rbmqConnectionManager.connect(amqp, RabbitMQHostURL);
rbmqChannel = await rbmqConnectionManager.createConfirmChannel(rbmqConnection);
})();
//Error Here: None of the parameter is passed to the callback function
app.use('/enqueue', publishingRoute.enqueueUser(rbmqChannel, RabbitMQQueueName, RabbitMQRoutingKey, RabbitMQExchange));
app.listen(PublishingServerPort , async () => {
console.log(`Server listening on ${PublishingServerPort }`);
})
../routes/ contains modules, that handles the routes from the publisher.js. One of the routes's module is the enqueue.js. It enqueues JabberID of the users (JSON) into the RabbitMQ queue, through the Exchange. The following code are of enqueue.js module.
'use strict';
const router = require('express').Router();
const PublisherService = require('../services/rbmq-publisher');
export function enqueueUser(amqpChannel, queueName, routingKey, exchange) {
//Error: No parameter has reached here. amqpChannel, queueName, routingKey, and exchange are undefined. I need all of them here.
router.post('/', async (req, res) => {
const content = req.body.payload;
await PublisherService.PublishPayload(amqpChannel, exchange, routingKey, content);
res.status(200);
res.send({
"Message": "OK",
"payloadEnqueued": content
});
});
return router;
}
rbmq-publisher.js is the controller (module) for handling publishing/enqueuing into the RabbitMQ Exchange. The following code is of the rbmq-publisher.js
'use strict';
const PublishPayload = async function(channel, exchange, routingKey, content) {
//Error: None of the parameter has reached here. All of them are undefined.
console.info(`[AMQP] : Publishing Message ...`);
try {
await channel.publish(exchange, routingKey, Buffer.from(JSON.stringify(content)));
console.log(`[AMQP SUCCESS]: JabberID Published`);
}
catch(exception) {
//This is what is being shown in the console window. I have written the error below this code snippet
console.error(`[AMQP ERROR]: ${exception}`);
}
};
export {
PublishPayload
};
Console windows shows the following error:
[AMQP ERROR]: TypeError: Cannot read property 'publish' of undefined
None of the arguments from the app.use() has reached the callback function. Where did I go wrong?

Mongoose not resolving callback queries?

I have been working on this project for 2 years now, and I'm thinking this was caused by the recent update, but am wondering if there are any kind, intelligent, Mongoose/NoSQL DBA, souls out there who would do the awesome service of helping me either track-down, and/or resolve this issue.
So, as you can see below, this is a simple mongoose find query over express to MongoDB. This is rather evident, at a high-level, and for most devs, the interactions will be natural, as any Mongo, Express, Node Stack using Mongoose.
The is issue is that, when I send this query, disregarding environment (a production project), it does not resolve.
The "data" seems to get lost somewhere, and therefore, the query simply never resolves.
It's a simple setup, really a test endpoint, so help out, run it through, and send some feedback.
Greatly Appreciated!
Model.js
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate');
const Schema = mongoose.Schema;
const TestSchema = new Schema({
data: {
type: String,
unique: false,
required: true
},
}, {
timestamps: true
});
TestSchema.plugin(mongoosePaginate);
module.exports = mongoose.model('Test', TestSchema);
Constructor.js
class Constructor {
constructor() {}
getAll() {
return TestSchema.find({}, function (err, tests) {})
}
}
module.exports = Constructor
db.js
let mongoose = require('mongoose')
// Connect to db
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true, useUnifiedTopology: true }, err => {
if (err)
return console.log("Cannot connect to DB")
connectionCallback()
console.log("DB Connected")
});
let connectionCallback = () => {}
module.exports.onConnect = cb => {
connectionCallback = cb
}
App.js
const express = require('express');
const app = express();
const ip = require('ip');
let db = require('./db')
const router = express.Router();
const port = 8888;
const http = require('http').createServer(app);
let ipAddress = 'localhost'; // only works to the local host
try {
// will enable the server to be accessed from the network
ipAddress = ip.address();
} catch( err ){
console.err( err );
}
http.listen(port, ipAddress,
() => {
let message = [
`Server is running at ${ipAddress}:${port}`,
];
console.log( ...message )
});
db.onConnect(() => {
let Constructor = require("./pathTo/Constructor")
let construct = new Constructor()
app.use('/api', router.get('/test', function(req, res) {construct.getAll()}))
})
Your problem is with the constructor.js getAll function, as you are returning also and passed a callback also, the promise will never be resolved. You should either resolve the promise or return the response from the callback.
Resolve Promise:
class Constructor {
constructor() {}
async getAll() {
return await TestSchema.find({})
}
}
module.exports = Constructor
Return from callback:
class Constructor {
constructor() {}
getAll() {
TestSchema.find({}, function (err, tests){
return tests.
})
}
}
module.exports = Constructor
I ended up just scaling the project for production. I put the connectionCallback in a class and called it with the createConnection mongoose function.
Looks like this:
mongoose.Promise = global.Promise;
const url = 'mongodb://localhost/db'
const connection = mongoose.createConnection(url, options);
//load models
require('/models').connectionCallback();
modules.export = connectionInstance;
Please note, I am no longer using express!

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