Mongoose Populate returns empty array

走远了吗. 提交于 2019-12-12 01:04:30

问题


I am receiving an empty array with the following code:

var mongoose = require('mongoose');
var db = mongoose.createConnection('localhost', 'mytestapp');

var SurveySchema = require('../models/Survey.js').SurveySchema;
var Survey = mongoose.model('SurveySchema', SurveySchema, 'surveys');


var UserSchema = require('../models/Survey.js').User;
var User = mongoose.model('user', UserSchema, 'users');

exports.getSurveysForUser = function(User) {
    return function (req, res) {


 User
        .findOne({_id: req.params.userId})
        .populate('surveys')
        .exec(function (err, user){
            if (err) return res.json({error: err})
            else {
                var surveyList=[];
                surveyList = user.surveys;
                console.log(surveyList);
                console.log("user: "+ user);
                res.json(surveyList);

            }
        });
}};

This is the console output:

 [ ]

user: { __v: 2,
  _id: 52939b8c22a7efb720000003,
  email: 'a@b.de',
  password: '202cb962ac59075b964b07152d234b70',
  surveys: []
}

These are the Mongoose models:

exports.SurveySchema = new Mongoose.Schema({
description : String,
questions : [question] });

exports.User = new Mongoose.Schema({
name : String,
email: { type: String, unique: true },
password: { type: String, required: true},
surveys :  [{type: Schema.ObjectId, ref: 'SurveySchema'}] });

Btw:

I already tried User.findOne(...) and then a Survey.find() in the callback. It seemed that the second statement was not even executed. Apparently i am very new to mongoose..and i can't find a way around this problem

Do you have any ideas how to help me? I couldn't really find any helpful solution here, but the problem shouldn't be a big one. Thanks in advance, its really keeping me up for days now!!

Edit: So this is the index.js with the method:

var mongoose = require('mongoose');
var db = mongoose.createConnection('localhost', 'mytestapp');

var SurveySchema = require('../models/Survey.js').SurveySchema;
var Survey = mongoose.model('SurveySchema', SurveySchema, 'surveys');



var UserSchema = require('../models/Survey.js').User;
var User = mongoose.model('user', UserSchema, 'users');

//.. here are some more methods.. 

exports.getSurveysForUser = function(User) {
return function (req, res) {
 User
            .findOne({_id: req.params.userId})
            .populate('surveys')
            .exec(function (err, user){
                if (err) return res.json({error: err})
                else {
                    var surveyList=[];
                    surveyList = user.surveys;
                    console.log(surveyList);
                    console.log("user: "+ user);
                    res.json(surveyList);

                }
            });
}};

//this is the code, that saves a response to a survey

exports.addResponse = function(ResponseSet) {
    return function (req, res) {
        console.log("bin da: addResponse");
        console.log("response zu: " + req.body.surveyId);
        console.log("von user : " + req.body.userId);

        //für user speichern

        var pUser = User.findOne({_id:req.body.userId}, function (error, user) {

                // Maybe populate doesnt work, because i only push the ID?

               user.surveys.push(Mongoose.Types.ObjectId(req.body.surveyId));

               user.save();

            }
        );



        var pSurvey = Survey.findOne({_id:req.body.surveyId}, function (error, survey) {
                survey.responses.push(Mongoose.Types.ObjectId(req.params.id));
                survey.save();
            }
        );



        //responseSet speichern

        var responseSet = new ResponseSet(req.body);
        responseSet.save(function(error, responseSet) {
            if (error || !responseSet) {
                res.json({ error : error });
            } else {

                res.json(responseSet);
            }
        });
    };

 };

And this is the app.js, which consumes the index.js:

var Mongoose = require('mongoose');
var db = Mongoose.createConnection('localhost', 'mytestapp');

var SurveySchema = require('./models/Survey.js').SurveySchema;
var Survey = db.model('surveys', SurveySchema);
var UserSchema = require('./models/Survey.js').User;
var User = db.model('user', UserSchema);

var ResponseSetSchema = require ('./models/Survey.js').responseSet;
var ResponseSet = db.model('responseSet', ResponseSetSchema);

var express = require('express')
  , routes = require('./routes')
  , http = require('http')
  , path = require('path')
  , passport = require('passport')
  , pass = require('./config/pass')

  , user_routes = require('./routes/user');

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views/app');
//app.engine('html', require('ejs').renderFile);
app.use(express.static(__dirname + '/views/app'));
app.use(express.cookieParser());
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session({ secret: 'securedsession' }));
app.use(passport.initialize()); // Add passport initialization
app.use(passport.session()); // Add passport initialization
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

app.all('/secure', pass.ensureAuthenticated);


app.get('/', function (req, res)
{
    res.render('index.html');
} );

// some more code... 

app.get('/api/secure/userSurveys/:userId', routes.getSurveysForUser(User));

http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

Hope it helpsto fight the problem! Many many thanks in advance!! :)


回答1:


Try changing:

surveys: [{type: Schema.ObjectId, ref: 'SurveySchema'}] });

to

surveys: [{type: Schema.Types.ObjectId, ref: 'SurveySchema'}] });

Also, make sure you have surveys pushed as children to User.surveys.

http://mongoosejs.com/docs/populate.html, here this section talks about your requirement in detail:

Refs to children

We may find however, if we use the aaron object, we are unable to get a list of the stories. This is because no story objects were ever 'pushed' onto aaron.stories."

Ok, it took quite a lot to figure out the issue:

exports.getSurveysForUser = function(User) {
...
};

The var User - model is not being injected into the scope properly. Change to:

exports.getSurveysForUser = (function(User) {
...
})(User);

The returned function's signature for middleware do not require User model to be passed as they are re-initiated and passed within the middleware code.

In index.js, change this

app.get('/api/secure/userSurveys/:userId', routes.getSurveysForUser(User));

to

app.get('/api/secure/userSurveys/:userId', routes.getSurveysForUser());

I also request you to self test your code and read as many docs as possible. Also, there can be multiple ways of reaching your goals. With time and practice you will conquer them all. Good luck!




回答2:


So i found a solution! Firstly it seemed, that the mongoose Schemas were not correctly required.

So in the models, i did mongoose.model('modelname', schemaname); for every model and now i only use mongoose.model(...) for every model in the index.js.

Secondly i found out about an even more critical thing: There were suddenly no user.surveys for my testuser anymore! I am sure that it was filled with surveys a few days ago. Because i tested my code several times and some surveys were pushed to that collection. Maybe i dropped the collection it in some testing..i don't really remember. So i pushed a survey manually in the mongodb console and tested it again --> worked! the user.surveys were populated! maybe the function worked yesterday and didn't need any change. I am so sorry, if that was a waste of time.

Bad thing is, that right now the exports.addResponse(....) is only saving a response, but is not pushing the IDs to the arrays user.surveys and survey.responses. This seems to be a synchronizing Problem and i will figure that out somehow.

Anyways, thank you for your help and time!



来源:https://stackoverflow.com/questions/20313517/mongoose-populate-returns-empty-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!