简体   繁体   中英

MEAN.JS Mongoose Populate in middleware does not work

Synopsis

I'm using MeanJS as a full web stack solution for a web application to list articles from users. It is very similar to the example provided by default by MEAN.JS.

Question

When I call the list of articles http://localhost:3000/articles , the result set has the user email and username associated with each article (through Mongoose Populate function). But when I retrieve a single article http://localhost:3000/articles/1234567890 , the user information are not associated with the article.

I have tried to use mongoose-relationsip plugin, and adding toObject: { virtuals: true }, toJSON: { virtuals: true } to the article model. Both did not work.

For more details, I have associated the controller, the router and the model of the article object.

Models

For simplicity, I have only included the necessary attributes for each object. Basically, I have an article object and a user object (btw: I'm using the same example provided by MEAN.JS).

articles.server.model.js 'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    relationship = require("mongoose-relationship");    

/**
 * Article Schema
 */
var ArticleSchema = new Schema({
    body: {
        type: String,
        default: '',
        trim: true
    },
    created: {
        type: Date,
        default: Date.now
    },
    user: {
        type: Schema.ObjectId,
        ref: 'User',
        childPath:"articles"
    },
    viewCount: {
        type: Number,
        optional: true,
    },
    comments:[{ 
        type:Schema.ObjectId, 
        ref:"Comment" 
    }],{ 
    strict: true,
    toObject: { virtuals: true },
    toJSON: { virtuals: true }
});    

ArticleSchema.plugin(relationship, { relationshipPathName:'user' });
mongoose.model('Article', ArticleSchema);

articles.server.routes.js

'use strict';

/**
 * Module dependencies.
 */
var users = require('../../app/controllers/users.server.controller'),
    articles = require('../../app/controllers/articles.server.controller');

module.exports = function(app) {
    // Article Routes
    app.route('/articles')
        .get(articles.list)
        .post(users.requiresLogin, articles.create);

    app.route('/articles/:articleId')
        .get(articles.read)
        .put(users.requiresLogin, articles.hasAuthorization, articles.update)
        .delete(users.requiresLogin, articles.hasAuthorization, articles.delete);

    // Finish by binding the article middleware
    app.param('articleId', articles.articleByID);
};

articles.server.controller.js

'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
    errorHandler = require('./errors.server.controller'),
    Article = mongoose.model('Article'),
    db=require('./databaseoperations'),
    _ = require('lodash');

/**
 * Show the current article
 */
exports.read = function(req, res) {
    res.json(req.article);
};
/**
 * List of Articles
 */
exports.list = function(req, res) {
    Article.find().populate('user', 'displayName email').exec(function(err, articles) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(articles);
        }
    });
};

/**
 * Article middleware
 */
exports.articleByID = function(req, res, next, id) {
    Article.findById(id).populate('user', 'displayName email').exec(function(err, article) {
        if (err) return next(err);
        if (!article) return next(new Error('Failed to load article ' + id));
        next();
    });
};

Any help will be very appreciated.

Thanks.

It looks like your article middleware is not adding the article to the req . Add this line before calling next() :

req.article = article;

In this part, you are not assigning result to req

    exports.articleByID = function(req, res, next, id) {
    Article.findById(id).populate('user', 'displayName email').exec(function(err, article) {
        if (err) return next(err);
        if (!article) return next(new Error('Failed to load article ' + id));
        req.article = article; //THIS PART IS MISSING
        next();
    });
};

So when you read single article by id, you return it from req.article

exports.read = function(req, res) {
    res.json(req.article);
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM