Tengo un problema cuando quiero mostrar una lista de datos de Mongoose (MongoDB) en mi front-end en ejs
Por ejemplo:
var User = require("./models/user"); var Houses = require("./models/house"); app.get("/", function(req, res){ var list_houses = []; for(var i=0; i<req.user.city.length; i++) { Houses.find({'city': req.user.city[i]}, function(err, result){ if(err)console.log(err); if(result){ list_houses = list_houses.concat(result);//add array result to array list_prices } }); } res.render("/prices_houses",{list_houses: list_houses}); });Encontré el módulo 'async', pero tampoco funciona, mi código era:
var User = require("./models/user"); var Houses = require("./models/house"); var async = require('async'); app.get("/", function(req,res){ var list_houses = []; async.waterfall([ async.each(req.user.city, function(result, callback){ Houses.find({'city': result}, function(err, result){ if(err)console.log(err); if(result){ list_houses = list_houses.concat(result); } }); }); ], function(arg1, callback){ res.render("/prices_houses", {list_houses: list_houses}); }); });Cuando quiero mostrar 'list_houses.length' en ejs, muestra esto: 0
<%=list_houses.length%>Mis esquemas en mangosta son:
var User = new mongoose.Schema({ city : [String] ... }); var House = new mongoose.Schema({ city: String price: Double });Sé que el problema es con Asynchronous, pero no sé cómo resolverlo. Por favor ayúdame con este problema.
Lo estás complicando demasiado, creo. Parece que puedes usar el operador $in para esto. Algo a lo largo de estas líneas:
Houses.find({'city': {$in: req.user.city}}, function(err, results){ if(err)console.log(err); console.log(results); // this should be an array of all houses in all cities that the user has in their city array });Sí, el problema es la naturaleza asíncrona de nodejs. No puede usar for loop ya que terminará antes de que cualquiera de las llamadas a la base de datos dé algún resultado. Como señaló Paul, debe usar las consultas proporcionadas por mongo cuando usa array. Pero este es un patrón común que puede usar si necesita hacer varias llamadas a bases de datos.
var User = require("./models/user"); var Houses = require("./models/house"); app.get("/", function(req, res){ var list_houses = []; var index = req.user.city.length; function findHouses(i, arr, cb){ //databases call here Houses.find({'city': arr.city[i]}, function(err, result){ if(err)console.log(err); if(result){ cb(result); } else{ cb(null); } }); } findHouses(index--, req.user.city, function(result){ if(result && index>=0){ list_houses = list_houses.concat(result); findHouses(index--, req.user.city); } else if(index == 0){ res.render("/prices_houses",{list_houses: list_houses}); } }); });este código debería funcionar bien, he usado la devolución de llamada
app.get("/", function(req, res){ function listhouses(cb){ var list_houses = []; for(var i=0; i<req.user.city.length; i++) { Houses.find({'city': req.user.city[i]}, function(err, result){ if(err)console.log(err); if(result){ list_houses = list_houses.concat(result);//add array result to array list_prices } }); } cb(list_houses); } listhouses(function(list_houses){ res.render("/prices_houses",{list_houses: list_houses}); }); });