Search code examples
angularjsnode.jsmongodbmongoosemeanjs

AngularJS to Mongoose params on queries


I'm using the mean stack and I can´t figure out how to pass params to mongoose query from the angular controller.

From the mean stack (https://github.com/meanjs/mean) example, we have:

On the server side

an article model

/**
 * Article Schema
 */
var ArticleSchema = new Schema({
    created: {
        type: Date,
        default: Date.now
    },
    title: {
        type: String,
        default: '',
        trim: true,
        required: 'Title cannot be blank'
    },
    content: {
        type: String,
        default: '',
        trim: true
    },
    user: {
        type: Schema.ObjectId,
        ref: 'User'
    }
});

mongoose.model('Article', ArticleSchema);

an article controller with a function to obtain a list of all articles and another function to obtain an article by Id

    /**
 * List of Articles
 */
exports.list = function(req, res) {
    Article.find().sort('-created').populate('user', 'displayName').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').exec(function(err, article) {
        if (err) return next(err);
        if (!article) return next(new Error('Failed to load article ' + id));
        req.article = article;
        next();
    });
};

and the articles routes

    /**
 * 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);
};

on the client side

we have an articles module with a routes config file

// Setting up route
angular.module('articles').config(['$stateProvider',
    function($stateProvider) {
        // Articles state routing
        $stateProvider.
        state('listArticles', {
            url: '/articles',
            templateUrl: 'modules/articles/views/list-articles.client.view.html'
        }).
        state('viewArticle', {
            url: '/articles/:articleId',
            templateUrl: 'modules/articles/views/view-article.client.view.html'
        });
    }
]);

an articles controller

angular.module('articles').controller('ArticlesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Articles',
function($scope, $stateParams, $location, Authentication, Articles) {
    $scope.authentication = Authentication;

    $scope.find = function() {
        $scope.articles = Articles.query();
    };

    $scope.findOne = function() {
        $scope.article = Articles.get({
            articleId: $stateParams.articleId
        });
    };
}
]);

and a list view

<section data-ng-controller="ArticlesController" data-ng-init="find()">
<div class="page-header">
    <h1>Articles</h1>
</div>
<div class="list-group">
    <a data-ng-repeat="article in articles" data-ng-href="#!/articles/{{article._id}}" class="list-group-item">
        <small class="list-group-item-text">
            Posted on
            <span data-ng-bind="article.created | date:'mediumDate'"></span>
            by
            <span data-ng-bind="article.user.displayName"></span>
        </small>
        <h4 class="list-group-item-heading" data-ng-bind="article.title"></h4>
        <p class="list-group-item-text" data-ng-bind="article.content"></p>
    </a>
</div>
<div class="alert alert-warning text-center" data-ng-if="articles.$resolved && !articles.length">
    No articles yet, why don't you <a href="/#!/articles/create">create one</a>?
</div>

My question is:

If I want to find all the article of a user, how can I pass a variable param to the find() function in the angular view?

I thought that the Articles.query() in the angular controller works as a mongodb or mongoose command, but I wasn't able to implement it.


Solution

  • Pass an object in query() method and it will be sent to server as query variables. In server use req.query to get those variables:

    Client:

    $scope.articles = Articles.query({user: 'user_id'});
    

    Server:

    Article.find({user: req.query.user}).sort('-created').populate('user', 'displayName').