2017-02-22 60 views
0

我想在每次调用express express时执行一个函数。在渲染express之前执行函数获取路由器NodeJS

我知道我可以简单地将函数放在app.get函数中,但我想多次调用相同的函数。

这里是我的router.js文件

var Setting = require('../models/setting'); 
module.exports = function(app, passport) { 

// ===================================== 
// HOME PAGE (with login links) ======== 
// ===================================== 
app.get('/', function(req, res) { 
    Setting.findOne(function(err, setting) { 
     if (err) 
      throw err; 
     // console.log(setting); 
     res.render('index', { title: 'eduBird | Reach the glory', setting: setting }); // load the index file 
    }); 
}); 

// ===================================== 
// LOGIN =============================== 
// ===================================== 
// show the login form 
app.get('/login', sabSettings, function(req, res) { 

    // render the page and pass in any flash data if it exists 
    res.render('login', { 
     message: req.flash('loginMessage'), 
     errors: req.flash('error'), 
     title: 'Login | eduBird', 
     setting: setting 
    }); 
}); 

// process the login form 

app.post('/login', passport.authenticate('local-login', { 
    successRedirect: '/profile', 
    failureRedirect: '/login', 
    failureFlash: true 
})); 

// ===================================== 
// SIGNUP ============================== 
// ===================================== 
// show the signup form 
app.get('/signup', function(req, res) { 

    // render the page and pass in any flash data if it exists 
    res.render('signup', { 
     message: req.flash('signupMessage'), 
     errors: req.flash('error'), 
     title: 'Register | eduBird', 
     setting: req.setting 
    }); 
}); 

// process the signup form 
app.post('/signup', passport.authenticate('local-signup', { 
    successRedirect: '/profile', 
    failureRedirect: '/signup', 
    failureFlash: true 
})); 

// app.post('/signup', function(req, res) { 
//  console.log(req); 
// }); 

// ===================================== 
// PROFILE SECTION ===================== 
// ===================================== 
// we will want this protected so you have to be logged in to visit 
// we will use route middleware to verify this (the isLoggedIn function) 
app.get('/profile', isLoggedIn, sabSettings, function(req, res) { 
    res.render('profile', { 
     user: req.user, // get the user out of session and pass to template 
     title: req.user.local.name + "'s profile | eduBird", 
     setting: req.setting 
    }); 
}); 

// ===================================== 
// LOGOUT ============================== 
// ===================================== 
app.get('/logout', function(req, res) { 
    req.logout(); 
    res.redirect('/'); 
}); 
}; 

// route middleware to make sure a user is logged in 
function isLoggedIn(req, res, next) { 

// if user is authenticated in the session, carry on 
if (req.isAuthenticated()) 
    return next(); 

    // if they aren't redirect them to the home page 
    res.redirect('/login'); 
    }; 

function sabSettings(next) { 
Setting.findOne(function(err, setting) { 
    if (err) 
     throw err; 
    console.log('sabSetting function executed'); 
    console.log(setting); 
    console.log('~~~~~~~~~~~'); 
    // return setting; 
    return next(setting); 
}); 
}; 

在这里,我曾使用过的正在执行罚款isLoggedIn的例子,但相同的是不能为sabSettings()工作,这将通过所有设置的配置从数据库到我的/login,/signup,/profile和/或/所有的路线。

console.log(setting)的所有数据返回到我的控制台,但我得到一个错误,指出:

throw er; // Unhandled 'error' event 
^

TypeError: next is not a function 
    at C:\Users\animeshweb\Desktop\projects\eb-v2\routes\routes.js:106:16 

你可以看到,我在app.get('/')嵌入功能得到相同的,但我想这函数在任何我想要的地方执行,所以我需要一个单独的函数。

更新

更新我routes.js的要求:

function sabSettings(req, res, next) { 
Setting.findOne(function(err, setting) { 
    if (err) 
     next(err); 
    console.log('sabSetting function executed'); 
    console.log(setting); 
    console.log('~~~~~~~~~~~'); 
    req.setting = setting; 
    next(); 
}); 

};

我上面也做了Setting = require(myModelURL),这对route.get'/'工作正常。

*这是我的看法/ layout.pug file`

link(rel='icon', type='image/png', href=setting.logo.logo16 sizes='16x16') 
link(rel='icon', type='image/png', href=setting.logo.logo32 sizes='32x32') 
link(rel='icon', type='image/png', href=setting.logo.logo128 sizes='128x128') 

同样在adminlayout0.pug工作正常

感谢。

回答

1

您声明sabSettings错误。中间件是三个参数让你的声明应该是这样的:

function sabSetting(req, res, next) { 
    // function logic here 
} 

既然你叫next的说法是错误的位置,当你尝试调用它不是一个功能。我不知道你为什么试图做return next(setting)。这将告诉Express,您正在报告请求中的错误。如果你试图把setting价值的地方,请求处理程序的其他部分可以使用它,那么你可能希望把它放在req对象,如:

req.setting = setting; // put setting on the req object for other code to use 
next();     // continue routing 

此外,你不应该做的一个中间件功能中的throw err。这根本不会做任何有用的事情,你的请求可能永远不会完成。相反,你应该在得到它时处理错误。当出现错误时,您可以在中间件内分支到备用策略,或者您可以简单地通过next(err)res.status(500).send(...)返回失败的请求。

然后,您将需要改变你的res.render()这样:

res.render('index', { title: 'eduBird | Reach the glory', setting: req.setting }); 

setting变量现在存储在req对象上,这样就是你需要参考它。

在你指的是setting的任何地方改变它。

+0

更新我的'sabsetting()'那些提到: 功能sabSettings(REQ,水库,下一个){ Setting.findOne(函数(ERR,设定){ 如果(ERR) 的console.log( ''sabSetting function executed'); console.log(setting); console.log('~~~~~~~~~~~'); req.setting = setting; next(); }) ; }; 但是它仍然显示'无法读取未定义的属性'标识'的错误,我在问题中添加了我的.pug视图。 –

+0

我刚刚更新了我的问题,还有更多我错过了route.js'sabsetting()'? –

+0

@AnimeshSingh - 你看过'setting'变量,看看它是否有所需的'setting.logo'属性吗?而且,当你调用'res.render()'时,你需要传递'setting:req.setting'而不是'setting:setting',因为这是你存储'setting'变量的地方。 – jfriend00