How to pass data through middlewares using Loopback? - node.js

I'm actually using loopback, and here is my needs:
I have two middlewares triggered by a POST request on /api/Orders/, and I need middleware 1 to pass data to middleware 2.
For example:
middleware1.js
module.exports = function() {
return function firstMiddleware(req, res, next) {
var toPass= "string to pass to second middleware";
next();
};
}
middleware2.js
module.exports = function() {
return function secondMiddleware(req, res, next) {
//Do whatever to get passed value from middleware1
};
}
I did not found anything useful in the official documentation talking about this, but I may have missed it.
Thanks.

In middleware1 you can update req object and access the variable in the middleware2.
middleware1.js
module.exports = function() {
return function firstMiddleware(req, res, next) {
var toPass= "string to pass to second middleware";
req.locals = { toPass };
next();
};
}
middleware2.js
module.exports = function() {
return function secondMiddleware(req, res, next) {
console.log(req.locals.toPass);
next();
};
}

Related

Stop execution Express.js

I want to stop execution if a determinate param is true when I called a function. Is that possible?
The only way I found to do that is returning a boolean in check function and depend of it do a return or not in router.get.
router.get('/', function(req, res){
check(req, res, true);
console.log(1);
res.render('page1', {});
});
function check (req,res,param = false){
if (param){
res.render('page2');
// Stop it here
}
else {
return("hi");
}
}
Something like this (I assume that function check_param return true if your parameter param set).
router.get('/',[function(req,res,next) {
if (check_param()) {
res.render('page2');
}
else {
next();
}
},function(req,res) {
res.render('page1',{});
}])
You can create a middleware and add param check logic there so that you can use it for multiple routes.
router.get('/', check, function(req, res){
res.render('page1', {});
});
function check (req, res, next){
if (req.param){
res.render('page2');
}
else {
next()
}
}

Express: Show value from external request as response

I have the following function where I am using the cryptocompare npm package:
getPrice: function(coin){
cc.price(coin, 'USD')
.then(prices => {
console.log(prices);
return prices;
}).catch(console.error)
}
// https://github.com/markusdanek/crypto-api/blob/master/server/helper/cryptocompare.js
Now I want to set up an Express server to open http://localhost:9000/current and to display the current "price".
So I have my controller which looks like this:
module.exports = {
getCurrentPrice: function(req, res, next) {
getPrice('ETH', function(price);
}
};
// https://github.com/markusdanek/crypto-api/blob/master/server/controllers/CryptoController.jshttps://github.com/markusdanek/crypto-api/blob/master/server/controllers/CryptoController.js
My route:
var controllers = require('../controllers'),
app = require('express').Router();
module.exports = function(app) {
app.get('/current', controllers.crypto.getCurrentPrice);
};
When I open now http://localhost:9000/current I only get the current price in my console, but not in my browser.
How can I also set the response to the value?
I tried this but failed:
module.exports = {
getCurrentPrice: function(req, res, next) {
getPrice('ETH', function(price){
res.status(200).json(price);
});
}
};
I guess thats the wrong way to call a callback.. do I have to modify my helper function or anything else?
My project is also on Github for further references: https://github.com/markusdanek/crypto-api
below may help you
module.exports = {
getCurrentPrice: function(req, res, next) {
cc.price('ETH', 'USD')
.then(prices => {
console.log(prices);
res.json(prices)
})
.catch(err=>{
console.error(err)
return next(err);
})
}
};

Calling a middleware from within a middleware in NodeJS/ExpressJS

I have created some standard middleware with some logic, and depending on the logic I need to call some 3rd party middleware.
Middleware is added using app.use(), which is where I add my custom middleware.
Once in my middleware I no longer have access to app.use(), how do I call the middleware?
Here is some code:
Any ideas ?
const customerData = (req, res, next) => {
try {
console.log('Started');
if (process.env.STORE_CUSTOMER_DATA === 'true') {
// Here is some custom middleware that doesn't belong to me
//
// Returns a function (I confirmed it) ready to be called with res,req, next
//
let externalMiddlware = logger({
custom:true
});
// Do I return it ? Call it ? Trying everything and nothing seems to work
externalMiddlware(req,res,next); // ???
} else {
// DO not call external middleware, will break out of if and then call next()
}
console.log('Finished');
next();
} catch (err) {
next(err);
}
};
module.exports = customerData;
I think this should work but if you delegate the callback to this other externalMiddlware you should not call next() in customerData use this 3rd middleware
so have you try
const customerData = (req, res, next) => {
try {
console.log('Started');
if (process.env.STORE_CUSTOMER_DATA === 'true') {
let externalMiddlware = logger({
custom:true
});
return externalMiddlware(req,res,next);
} else {
return next(); // <= next moved
}
} catch (err) {
next(err);
}
};
module.exports = customerData;

How to pass arguments to nodejs modules

I am using nodeJS, and I want to pass argument to the module like this
function (req, res, next) {
var test = require('test')({key: 'abc'});
}
and when I write my module like this, I am able to get the value of key inside module
module.exports= function(key) {
console.log(key);
}
But If I write my module like this:
exports.fun1 = function(req, res, next) {
//something here
}
exports.fun2 = function(req, res, next) {
//something here
}
then how can I get the value of my argument ?
you can save it in a local var or make a constructor like function in your module
something like this
var _arg1, _arg2;
module.exports = {
ctor: function(arg1, arg2, etc) {
_arg1=arg1;
_arg2=arg2
},
moreFunction: function() {
//use _arg1 etc
}
}
and then usage will be:
var myModule = require('myModule');
myModule.ctor("bla", 2, null);
myModule.moreFunction();
You almost had it. You make your exports be a single function that accepts your arguments and then you return from that function the module contents like this:
Usage:
var test = require('test')({key: 'abc'});
function (req, res, next) {
test.fun1(yourArgsHere);
}
In your module:
// module constructor function
module.exports = function(options) {
console.log(options);
return {
fun1: function(req, res, next) {
// can access options.key here
// something here
},
fun2: function(req, res, next) {
// can access options.key here
// something here
}
};
}

nodeJS (express,connect) - Dynamically add middleware in current flow

I am currently working on formBuilder (client javascript <=> JSON <=> node), so i need effective way to handle JSON data on server. All forms are bind on one route, catched by middleware, so i need something like this:
Code is simplified (no regexs, req validators etc ..)
var middleware = require('../middleware'); // simple dir to object export
exports = module.exports =function(req,res,next) {
if(req.xhr && req.is('application/json')) {
var i, items = req.body.events.length;
for(i = 0; i < items; i++) {
var event = req.body.events[i];
if(middleware.forms[event] {
// -----------------
and here add that middleware into current flow ..
// -----------------
}
}
} else {
return next();
}
Easiest way is to prepare list of middleware, which will be used and call them in final route witch async .. but that i donw regard this as good way ..
So, i there any way to add requested middlwares to current flow, but before filan route ?
Middleware are just functions. So there is nothing wrong with just calling them. I had the same problem last week and I wrote a little helper.
var walkSubstack = function (stack, req, res, next) {
if (typeof stack === 'function') {
stack = [stack];
}
var walkStack = function (i, err) {
if (err) {
return next(err);
}
if (i >= stack.length) {
return next();
}
stack[i](req, res, walkStack.bind(null, i + 1));
};
walkStack(0);
};
You can use it with an array or just one function.
walkSubstack(middleware, req, res, next);
//or
walkSubstack([middleware, middleware], req, res, next);
I wrote something very similar:
let isActive1 = false;
let isActive2 = false;
let func1MD = (req, res, next) { /* ... */ }
let func2MD = (req, res, next) { /* ... */ }
let middleware = (function () {
// middleware #1
function func1(req, res, next) {
if (!isActive1) { return next(); }
return func1MD.call(null, req, res, next);
}
// middleware #2
function func2(req, res, next) {
if (!isActive2) { return next(); }
return func2MD.call(null, req, res, next);
}
// Returning an array of all middlewares to be called sequentially
return [
func1,
func2
]
})();
app.use(middleware);

Resources