Access another module.exports function from the same file node.js - node.js

To make it a bit more clear to what I'm trying to achieve.
I have a server running which includes many module, and one of the module use to check if the user role is an admin or not.
in Server.js
var loginAPI = require('myModule')(argStringType),
express = require('express');
var app = express();
Now that in the myModule.js I have few functions that already been implemented and just wanted to add one more, but this function really doesn't need to be call from the server.js instead it will be call once the person visit the URL, so I want to add something like this to the myModule.js
in myModule.js
app.get( "/post/:postid", function( req, res ) {
var id = req.param('postid');
return getContent( postid );
});
// Module.exports
module.exports = function ( arg ) {
return {
getContent: function ( id ) { },
getHeader: function ( id ) { };
};
So as you can see from the above, I have two function which is in the module.exports and they worked fine no problem except the one which is outside the module.exports that one work if I don't try to call the getContent, but that is what I'm trying to achieve. When someone visit the site by entering the URL in that format the app.get should be fire and do whatever is implemented to do.

Make sure you realize each module in Node.js has its own scope. So
ModuleA:
var test = "Test output string";
require('ModuleB');
ModuleB:
console.log(test);
Will simply output undefined.
With that said, I think this is the style of module you're looking for:
server.js:
var app = //instantiate express in whatever way you'd like
var loginApi = require('loginModule.js')(app);
loginModule.js:
module.exports = function (app) {
//setup get handler
app.get( "/post/:postid", function( req, res ) {
var id = req.param('postid');
return getContent( postid );
});
//other methods which are indended to be called more than once
//any of these functions can be called from the get handler
function getContent ( id ) { ... }
function getHeader ( id ) { ... }
//return a closure which exposes certain methods publicly
//to allow them to be called from the loginApi variable
return { getContent: getContent, getHeader: getHeader };
};
Obviously, adjust to fit your actual needs. There are lots of ways to do the same type of thing, but this fits closest with your original example. Hopefully that helps.

Related

Unable to call a local function on ExpressJS

I'm learning to develop a Rest API using NodeJs with Express JS. I build a controller to do my stuff inside it. I want to call a local function inside the controller but it is not working. I always get not defined error.
Hear is my Controller,
const db = require('../config/db');
class TransactionController {
constructor(){
}
generateCustomerTransaction(req, res) {
const program_id = req.params.program_id;
const customerList = getCustomerList(program_id); //error here
//Do some business logics
return res.json(result);
};
getCustomerList(program_id) {
//Do some query to get a list of result
return results;
}
}
module.exports = SeatExcelController;
Everything seems simple like others languages but I get
ReferenceError: getCustomerList is not defined
I have no idea how to simply call a local function.
Please help. Thanks a lot.
To be able to access your function that way it needs to be defined on the package scope outside the class as in:
const db = require('../config/db');
const getCustomerList(program_id) = () => {
// Do some query to get a list of result
return results;
}
class TransactionController {
generateCustomerTransaction(req, res) {
const program_id = req.params.program_id;
const customerList = getCustomerList(program_id); //error here
//Do some business logics
return res.json(result);
};
}
module.exports = SeatExcelController;
Or call your function with this before the call as in:
const db = require('../config/db');
class TransactionController {
generateCustomerTransaction(req, res) {
const program_id = req.params.program_id;
const customerList = this.getCustomerList(program_id); //error here
//Do some business logics
return res.json(result);
};
function getCustomerList(program_id) {
// Do some query to get a list of result
return results;
}
}
module.exports = SeatExcelController;
I would go for the first option if the function doesn't need to access any class variables.
You could also make this a static function if it is not related to the class:
static getCustomerList(program_id) {
//Do some query to get a list of result
return results;
}
and call the function like this:
TransactionController.getCustomerList(program_id)
or just call the function using the this keyword. Because the way you code it now, the function is belonging to your class and class dependent.
: this.getCustomerList(program_id)

JSON object persisting state from previous calls in nodejs express

In my express code I have a config in json, refer to the "template" variable below. I am doing some modifications in it for some purpose in call one and then in my second call when I am trying to get it, it is returning the modified value of field xyz that is A while I expect it to return the original config.
I did try to move that first line "const template = xxx" inside each method so that a new object gets created but it is still having the same issue. How can I fix this?
const express = require("express");
const { db, pgp } = require("../../helpers/dbConnection");
const { auth } = require("../middlewares/Auth");
const router = express.Router();
const template = require('../../config/template.json');
router.get("/callone", async (req, res) => {
try {
template.xyz = "A"
return res.status(200).send();
}
catch (err) {
return res.status(500).send(err.message);
}
});
router.get("/calltwo", async (req, res) => {
try {
return res.status(200).send(template);
}
catch (err) {
return res.status(500).send(err.message);
}
});
This approach is generally a bad idea.
It doesn't work if you ever want to scale beyond 1 server.
It doesn't work when there's more than 1 user using the system at the same time.
The right way to handle something like this is by adding either a database, or a session system.
Sessions feels like the right approach here, because that concept is specific for letting you store information specific to a user, and store/retrieve that over the course of several requests.

Calling a stored procedure with sequelize and an express API

This is probably pretty easy but I've been unable to piece it together properly.
I'm trying to use the Sequelize NPM to call a stored procedure that I built and then I want to trigger it with a GET request from from an express api and return the output of the procedure to the api.
Here is what my code looks like for the Sequelize portion....
// Testing stored procedure //
const Retrieve = (testName) => connection.testdata_connection.query("EXEC [SPROC] [INPUTS]")
module.exports = {
tests: Tests(),
retrieve: Retrieve()
};
This part "connection.testdata_connection" is just establishing my connection to the database and I have tested this and I know this part is set.
I would like to be able to hit that with something like...
const query = require('./database/queries'); ///Imports sequelize queries
const app = express();
app.get('/decrypt', function(req,res){
query.retrieve()
})
})
This doesn't work at all.
Now if I do something like this in the queries file...
const Retrieve = async function() {
const decrypt = await connection.testdata_connection.query("EXEC [SPROC] [INPUT]")
console.log(decrypt)
}
module.exports = {
tests: Tests(),
retrieve: Retrieve()
};
This will log to my console with correct data when I start the server. I want it to do that when I hit it with my endpoint.
First, your function should be exported but not executed:
// creating an async function (all i/o operations should be async).
const Retrieve = async(testName) => connection.testdata_connection.query("EXEC [SPROC] [INPUTS]")
module.exports = {
retrieve: Retrieve,
// retrieve: Retrieve() if you call the function with (), the function will be executed and we don't want that yet
};
Now we can call it in the route:
const query = require('./database/queries'); ///Imports sequelize queries
const app = express();
// the route is async because it is executing async code
app.get('/decrypt', async (req,res) => {
// waiting for the answer with await
const response = await query.retrieve();
// Doing something with the response
})
You still need to check for errors, but that is the basics.

Pass parameter to middleware function and return result

So guys, what I want to accomplish and not manage to get is to write a function that performs a query against database as a middleware, using req and res objects, and also can be used in a socket connection, to pass parameters to it and not use the req and res objects. Also I want it to return the result of the query. I tried using a middleware wrapper
function myFunc(param1, param2){
return (req, res) => {
here query
}}
works when hitting the endpoint with or without args i send, but dosnt work when i call the function from somewhere else
When you call myFunc you get returned a new function. You need to invoke that funcion, something like
myFunc('value1', 'value2')()
This will cause an error since you have no request or response object. These are express objects.
A better way to re-use the database code would be to put it in a function and inject that function to the middlewere.
E.g.
function getArticleById(id) {
return db.query('select * from articles where id = $1', [id])
}
Then create a middlewhere that takes this function in as dependency
function makeMiddlewere (getArticleById) {
return (req, res) => {
return articleById(req.query.id).then(articles => {
res.json(articles)
})
}
}
Then in your code you can do
Normal way
getArticleById(5).then(articles => {
console.log(articles)
})
Create the middlwere an
const express = require('express')
const getArticleById = require('./articlebyid')
const makeMiddlewere = require('./makemiddlewere')
const middlwere = makeMiddlwere(getArticleById)
const app = express.app
app.get('/article', middlewere)

KoaJS middleware and database access

If I had this to show an index for a users model:
app.use(route.get('/user', list));
function *list() {
var res = yield users.find({});
this.body = res;
};
Is it possible to put the database access part into its own middleware and then call next?
How could you pass the resulting list of users down to the next middleware? And somehow pass next through the route?
So the first middleware is any DB access needed, and the second middleware is presentation?
Essentially you attach the information to the request context or the this keyword within the middleware.
I created a screencast on writing middleware that might be helpful:
http://knowthen.com/episode-4-writing-middleware-in-koajs/
Here is an example of how you would pass information to downstream middleware.
let koa = require('koa'),
users = require('./users'),
app = koa();
function *firstMiddleWare (next) {
this.session = {
user: yield users.find({});
}
yield next;
}
function *secondMiddleware (next) {
// this.session.user is available here
yield next;
}
app.use(firstMiddleWare);
app.use(secondMiddleware);
app.use(function *(){
// this.session.user is available here as well
this.body = this.session.user;
});
app.listen(3000);

Resources