I'm using Node, Mongoose and Bluebird and am working on a site that serves up several RSS feeds.
When a feed is retrieved I want to pull any articles that I've already saved to my table from the table and combine them with any new articles in the feed into an array.I cannot seem to find a way to wait for the promises to all resolve before returning my array. The basic problem is that when loadRSSFeed is called it essentially immediately calls the return articleList line.How do I line all of this up so nothing is returned until my promises are all resolved?
This first function just sort of wraps everything:
function loadRSSFeed(rss, newsSource) {
var articleList = [];
// Promise.each(rss.channel[0].item, function (article) {
rss.channel[0].item.forEach(function (article) {
var item = {};
item.link = tryEval(article, "article.link[0]");
Promise(function() {
return getArticle(newsSource, article, item, articleList)
.then(function() {
return articleList;
})
})
})
};
The getArticle function looks like this:
function getArticle(newsSource, article, item, articleList) {
return Articles.findOne({ link: article.link }, function (err, doc) {
if (doc) {
articleList.push(doc._doc);
}
else {
item.title = tryEval(article, "article.title[0]");
item.pubDate = tryEval(article, "article.pubDate[0]");
item.sourceId = newsSource.id;
item.sourceName = newsSource.name;
if (item.pubDate) {
try {
item.pubDate = new Date(item.pubDate);
}
catch (err) {
item.pubDate = "";
}
};
item.contentSnippet = tryEval(article, "article.description[0]");
if (item.contentSnippet.indexOf("<") > 0) {
item.contentSnippet = item.contentSnippet.substring(0, item.contentSnippet.indexOf("<") - 1);
};
item.image = tryEval(article, "article['media:content'][0].$.url|article.thumbnail[0]");
if (!item.image) {
item.image = photoHunt(item);
if (item.image) {
item.contentSnippet = "";
}
};
if (item.title && item.link && (item.image || item.contentSnippet)) {
articleList.push(saveArticle(item));
}
}
})
}
and the saveArticle function looks like this:
function saveArticle(article) {
var curArticle = {};
if (article._id) {
curArticle = article;
curArticle._id = article._id;
curArticle.isNew = false;
}
else {
curArticle = new Articles();
curArticle.title = article.title;
curArticle.link = article.link;
curArticle.pubDate = article.pubDate;
curArticle.image = article.image;
curArticle.contentSnippet = article.contentSnippet;
curArticle.sourceName = article.name;
curArticle.sourceId = article.sourceId;
if (article.haters) {
curArticle.haters = article.haters;
};
if (article.lovers) {
curArticle.lovers = article.lovers;
};
if (article.readers) {
curArticle.readers = article.readers;
};
}
curArticle.save(function (err) {
if (err)
console.log(err);
});
return curArticle;
};
This is what the Articles model looks like, just in case there's an issue here:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
// NewsSchema = new Schema({ name: String });
var ArticlesSchema = new Schema({
title: String,
link: String,
pubDate: Date,
image: String,
contentSnippet: String,
sourceName: String,
lovers: [],
haters: [],
readers: [],
forumLinks: []
});
module.exports = mongoose.model('Articles', ArticlesSchema);