Answer the question
In order to leave comments, you need to log in
How to bind two models into one via iteration in node.js and mongoos?
There are two simple, one-to-many models.
1 - product
2 - product_info (there is a product_id field)
So, I'm trying to john all this. But it doesn’t work for me, it seems to me that something is certainly not right, but the problem is that the forEach loop runs faster than the data is pushed into the final array. And finally def.resolve(result); empty
var mongoose = require('mongoose');
var Q = require('q');
var catalog = function(app) {
var product = mongoose.model('product', require('../model/product'));
var productInfo = mongoose.model('product_info', require('../model/ProductInfo'));
var getAllProducts = function() {
var result = [];
var def = Q.defer();
product.find(function(err, products) {
products.forEach(function(product) {
productInfo.find({product_id: product._id}, function(err, info) {
product.info = info;
result.push(product);
});
});
def.resolve(result);
});
return def.promise;
};
return {
getAllProducts : getAllProducts
};
};
module.exports = catalog;
var products = require('../src/catalog')(app).getAllProducts();
products.then(function (products) {
console.log(products);
res.render('index', { products : products });
});
Answer the question
In order to leave comments, you need to log in
You have asynchronous code. Logically, def.resolve(result) will run before any of productInfo.find ends .
You need control over the execution of asynchronous code, like async .
product.find(function(err, products) {
async.each(products, function (product, cb) {
productInfo.find({product_id: product._id}, function(err, info) {
product.info = info;
cb(err);
});
}, function (err) {
def.resolve(products);
});
});
product.find(function(err, products) {
var p_ids = products.map(function (product) { // создаем массив id продуктов
return product._id;
});
productInfo.find({product_id : {$in: p_ids}}, function(err, infos) { // запрашиваем info для всех совпадающих id продуктов в массиве
var obj = infos.reduce(function(a, b) { // создаем коллекцию для быстрого поиска, где ключ - id продукта
return a[b.product_id ] = b;
}, {});
products.forEach(function (product) {
product.info = obj[product._id];
});
def.resolve(products);
}));
});
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question