I'm grabbing a request parameter from my route e.g. mydomain.com/topic/animals where requestParam = req.params.topicName and in this case, animals.
I loop through an object containing all possible topics, and then if I find a topicName that matches the requestParam, then I want to execute a call to the database to return all collections for that topic.
The problem is it's being executed synchronously because it'll always execute the else clause e.g.
if (requestParam === topicName) {
// fetch submission
} else {
// return 404
}
So it's always returning the 404, but if I get rid of the else clause here, then it works. I looked into underscore's _.after() but couldn't get it to work properly (and not even sure if that's what I should be using?
My code:
_.each(topics, function(key, topic) {
var topicName = key['topicName'],
if (requestParam === topicName) {
Submission.getTopicSubmissions({ topicName : topicName }, function(err, submissions) {
if (err) {
res.redirect('/');
} else if (submissions) {
res.render('topic', {
submissions: submissions
});
} else {
res.redirect('/topics');
}
});
} else {
res.render('errors/404', {
title: 'Page Not Found -',
status: 404,
url: req.url
});
}
});
The problem is that you should not render 404 inside the each iteration. Because you do an asynchronous lookup, it is scheduled to execute at some point in the future while the current function keeps going. Undoubtedly you're going to run into a different one at some point and render 404 at least once. Use a breakable iteration, mark when you search, and do 404 outside of the iteration, like so:
var isWaitingForResult = false;
topics.every(function(topic, key) { // TODO: Check if this iterator matches _.each
var topicName = key['topicName'],
if (requestParam === topicName) {
isWaitingForResult = true; // Wait for the result.
Submission.getTopicSubmissions({ topicName : topicName }, function(err, submissions) {
if (err) {
res.redirect('/');
} else if (submissions) {
res.render('topic', {
submissions: submissions
});
} else {
res.redirect('/topics');
}
});
return false; // stop iteration, we did start our search after all
}
return true; // continue iteration so we have another chance.
});
if (!isWaitingForResult) { // did a search NOT start?
res.render('errors/404', {
title: 'Page Not Found -',
status: 404,
url: req.url
});
}
Note that I am unsure whether I re-wrote each to every correctly. Check this. :)