Search code examples
node.jsexpressmongoosemongoose-schema

Wait for Getter in Mongoose to finish


I currently have two collections: tours and groups. As a tour can have mutiple groups I would like to count all groups that have the id of a specific tour and provide this on my tour endpoint.

Group = require("../models/groupModel");

var tourSchema = mongoose.Schema({
    title: String,
    currentSize: {type: Number, get: getCurrentSize},
    ...
});

function getCurrentSize(currentSize) {
    var persons = 0;
    Group.find({ tour: this.id }, function (err, groups) {
      for (var i = 0; i < groups.length; i++) {
        persons += groups[i].persons;
      }
      return persons;
    });
}

However currentSize does not even get returned if I am using this getter. If I delete it, it will return a value stored in the document.

Is there any way to achieve this? I already tried it as a async function that leads to some "Query already executed" error.


Solution

  • Okay, I somehow got completely on the wrong track. After some good sleep I figured out that a virtual is what I need.

    var tourSchema = mongoose.Schema({
        title: String,
        ...
    });
    
    tourSchema
      .virtual("currentSize", {
        ref: "group", // The model to use
        localField: "_id", // Find people where `localField`
        foreignField: "tour", // is equal to `foreignField`
      })
      .get(function (group) {
        var persons = 0;
        for (var i = 0; i < group.length; i++) {
          persons += parseInt(group[i].persons);
        }
        return persons;
      });
    

    In my tourController.js I can then use something like this:

    exports.index = async function (req, res) {
      const tours = await Tour.find({})
      .populate("currentSize")
      res.json(tours);
    }