I am declaring my function like this:
const parseConnections = (connectionsCSVPath, req, res) => {
//do a bunch of stuff
}
Inside the function, if I try to call res.locals.something, I get an error saying "cannot read property locals of undefined" I have tried several other syntaxes, such as this:
const parseConnections = ((connectionsCSVPath, req, res) => {
//do a bunch of stuff
})
this:
const parseConnections = (connectionsCSVPath, (req, res) => {
//do a bunch of stuff
})
and this:
const parseConnections = connectionsCSVPath, (req, res) => {
//do a bunch of stuff
}
and they all throw errors. What is the proper way to pass these 3 arguments to the function so that all 3 are defined inside?
Edit*: The function is then called like this:
router.post(
'/upload/engagements/batch', checkIfAuthenticated,
parseConnections('./tmp/connections.csv'),
parseMessages('./tmp/messages.csv'), (req, res) => {
//do a bunch of stuff
}
The problem is not (necessarily) with how you define the function but with how you are using it.
parseConnections('./tmp/connections.csv')
calls the function right then and there. You are only passing a single argument to it, so req
and res
will be undefined
.
function foo(a, b, c) {
console.log('a:', a);
console.log('b:', b);
console.log('c:', c);
}
foo('first argument');
However, you cannot pass values for req
and res
because these values are created and passed by express itself.
Essentially you are making the mistake of calling a function where you should be passing it. router.post
expects to be passed one or more functions. But you are calling parseConnections
and pass its return value instead which is probably undefined
.
Here is a simple example that demonstrates the difference:
function foo(x) {
console.log('inside foo', 'x is ', x);
}
// bar expects to be passed a function that it can call
function bar(callback) {
console.log('bar received:', callback);
try {
callback(42);
} catch(e) {
console.error(e);
}
}
// this will work as expected
console.log('Passing a function');
bar(foo);
// this will error because `bar` doesn't receive a function.
// this is what you are doing
console.log('Calling a function and passing its return value');
bar(foo(21));
One way to fix your problem is to make parseConnections
return a function, which is then received by router.post
. I'm using normal function declarations here so that the syntax is not too confusing:
function parseConnections(connectionsCSVPath) {
return function(req, res) {
//do a bunch of stuff
};
}
This requires no changes to your router.post
call.
Another solution is to pass a function to router.post
that calls parseConnections
instead, passing along req
and res
:
router.post(
'/upload/engagements/batch',
checkIfAuthenticated,
(req, res) => parseConnections('./tmp/connections.csv', req, res),
// alternatively you can use `.bind`:
// parseConnections.bind(null, './tmp/connections.csv'),
parseMessages('./tmp/messages.csv'), // <- this is likely wrong as well,
// but I leave this to you to figure out
(req, res) => {
//do a bunch of stuff
}
);