我最近开始重构旧的回调地狱路线以使用promises。 (注意:重构不完整所以下面的一些代码很难看)
这样做会破坏我的res.render()
功能。
基本的应用程序结构是一个复杂的调查/测验,可以将用户分为不同的类别。它存储它们的信息并在最后呈现自定义EJS页面。以下是最终通话的工作原理:
mongoose.model('Result')
.findOne({quizId: req.query.id})
.then(getPageData)
.then(renderPage)
.catch(errorHandler)
理论上很简单。
相关功能:
let getPageData = (mongooseResult) => {
let resultsPage;
let analyticsData;
if (mongooseResult.answers.section1.question1.answer != null && mongooseResult.answers.section1.question1.answer != undefined){
let resultsPage = WP.getPage(wp_pages_data, 'slug', mongooseResult.coreFit);
let analyticsData = {
quizId: mongooseResult.quizId,
coreFit: mongooseResult.coreFit,
secondFit: mongooseResult.secondFit,
degree: mongooseResult.answers.section1.question1.answer,
year: mongooseResult.answers.section1.question2.answer,
concentration: mongooseResult.answers.section1.question3.answer,
views: mongooseResult.views,
}
mongooseResult.views++;
mongooseResult.save();
return [resultsPage, analyticsData, mongooseResult];
} else {
throw new Error('S1Q1 IS UNDEFINED');
}
};
let renderPage = ([resultsPage, analyticsData, mongooseResult]) => {
if (resultsPage != null && resultsPage != undefined){
// WHY IS MY RENDER NOT WORKING???
res.render('templates/' + mongooseResult.coreFit, Object.assign({}, WP.get_WP_data(resultsPage), getPartials(mongooseResult.modules), analyticsData), (err, html) => {if (err) console.log(err); else res.send(html);});
} else {
throw new Error('GETTING PAGE DATA RETURNED UNDEFINED');
}
};
传入请求首先路由到/submit
POST路由 - 它操纵一些数据,将其全部存储在数据库中,然后res.redirect()
到/results?id=12345
GET路由,后者运行上面的逻辑。
render()
实际发射的是什么时髦!回调((err, html) => {if (err) console.log(err); else res.send(html);}
)将呈现的HTML发送到如果您在第二时间点击路线。
完成调查不会产生回复;但它成功地将所有信息存储在DB和console.logs中,客户端请求应该重定向到的ID。用这个生成的ID / URL命中GET路由,通过复制粘贴它,渲染就好了。
交换简单res.send('wtf')
的渲染工作 - 将实际响应发送到客户端。 (在本例中为字符串'wtf'...)
响应只是不发回数据。我不明白。有什么想法吗?
更新
奇怪的是,手动点击路线与我之前的POST请求中的重定向相比,使用简单的res.send('wtf mate')
产生不同的结果。
点击GET路线并手动将先前存在的ID传递给req.query:
在之前的POST请求res.redirect()
来电之后点击GET路线:
这可能更像Express请求类型不匹配问题?为什么res.redirect('/results?id=someString')
调用会改变URL而不是发回字符串/ HTML?
答案 0 :(得分:2)
根据您的更新,听起来您的res.send()
电话在客户端被奇怪地解释。 POST请求不应该影响URL栏,除非您特意告诉它 - 您是否检查过客户端最初发送此请求的位置?
我的猜测 - 因为您说上面发布的路由代码是在先前的POST路由上从res.redirect()
命中的 - 是客户端逻辑期望response
对象是URL字符串,并通过重定向首次点击GET路由,继承此响应对象。这样客户端就会尝试在URL栏中插入一大串HTML。
在这种情况下,手动点击GET路线,就像你说的那样,默认情况下只会从res.render()
呈现HTML - 但是res.redirect()
的初始点击可能不会。
答案 1 :(得分:1)
让我们尝试通过测试代码部分调试问题。
我有一些线索,其中一条就是'templates/' + result.coreFit
没有模板。
如果coreFit
文件夹中的文件具有相同的值名称,请尝试检查templates
值。
试试这段代码并告诉我它是否有效:
const
_ = require('lodash'),
mongoose = require('mongoose');
const getQuizResultById = quizId => {
return new Promise((resolve, reject) => {
const
Result = mongoose.model('Result'),
query = {
quizId
};
Result
.findOne(query)
.then(resolve)
.catch(reject);
});
};
const getPageData = result => {
if (_.get(result, 'answers.section1.question1.answer')) {
let resultsPage = WP.getPage(wp_pages_data, 'slug', result.coreFit);
let
analyticsData = _.pick(result, ['quizId', 'coreFit', 'secondFit', 'views']);
analyticsData.degree = _.get(result, 'answers.section1.question1.answer');
analyticsData.year = _.get(result, 'answers.section1.question2.answer');
analyticsData.concentration = _.get(result, 'answers.section1.question3.answer');
result.views++;
result.save();
return [resultsPage, analyticsData, result];
}
throw new Error('S1Q1 IS UNDEFINED');
}
const renderPage = ([resultsPage, analyticsData, result], res) => {
if (resultsPage) {
return res.render(
'templates/' + result.coreFit,
Object.assign({}, WP.get_WP_data(resultsPage), getPartials(result.modules), analyticsData),
(err, html) => {
if (err) {
console.log(err);
return res.status(500).send('Ooopsss...');
}
res.send(html);
});
}
throw new Error('GETTING PAGE DATA RETURNED UNDEFINED');
};
router.get('/results', (req, res) => {
getQuizResultById(req.query.id)
.then(getPageData)
.then(data => {
renderPage(data, res);
})
.catch(errorHandler);
});