Search code examples
javascriptnode.jsmongodbmongoosemongoose-schema

Mongoose returning empty array


I have a db in Mongo with 2 collections, users and campaigns. For the former, all of my requests (get,post, patch, etc...) work correctly. However, I am having an issue with campaigns.

I can create a new campaign in postman but not 'get' the campaigns. THe request appears successful but returns an empty array.

I have the campaigns split into: campaignController, ***Model, ***Routes,

and a handlerFactory to cover users and campaigns.

handlerFactory:

exports.getAll = Model =>
  catchAsync(async (req, res, next) => {
    // To allow for nested GET reviews on tour (hack)
    let filter = {};
    if (req.params.campaignId) filter = { campaign: req.params.campaignId };

    const features = new APIFeatures(Model.find(filter), req.query)
      .filter()
      .sort()
      .limitFields()
      .paginate();
    // const doc = await features.query.explain();
    const doc = await features.query;

    // SEND RESPONSE
    console.log('-------', doc);
    res.status(200).json({
      status: 'success',
      results: doc.length,
      data: {
        data: doc
      }
    });
  });

Campaign Model:

const campaignSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, 'Campaign name can not be empty!']
    },
    clientID: {
        type: String,
    },
    creator_id: {
        type: String,
    },
    budget: {
        type: Number,
        min: 100,
        required: [true, 'Campaign name can not be empty!']
    },
    startStatus: {
    type: String,
    enum: ['preStart', 'isStarted', 'preEnd'],
    default: 'preStart'
    },
    startDate: {
        type: Date,
    },
    createdAt: {
      type: Date,
      default: Date.now
    },
    updatedAt: {type: Date,
      default: Date.now
    },
    isDeleted: {
        type: Boolean,
        // required: [true, 'Must be true or false!']
        default: false
    },
    Priority: {
        type: Boolean,
        default: false,
    },
    location: {
        type: String,
        enum: ['Helsinki', 'Tallinn'],
        default: 'Helsinki'
    }
});

campaignSchema.pre('save', function(next) {
    if (!this.isModified('createdAt') || this.isNew) return next();

  this.updatedAt = Date.now() - 1000;
  next();
});

campaignSchema.pre(/^find/, function(next) {
  // this points to the current query
  this.find({ isDeleted: { $ne: false } });
  next();
});


const Campaign = mongoose.model('Campaign', campaignSchema);

module.exports = Campaign;

campaignController:

exports.getAllCampaigns = factory.getAll(Campaign);
exports.getCampaign = factory.getOne(Campaign);
exports.createCampaign = factory.createOne(Campaign);
exports.updateCampaign = factory.updateOne(Campaign);
exports.deleteCampaign = factory.deleteOne(Campaign);

exports.getMe = (req, res, next) => {
  req.params.id = req.campaign.id;
  next();
};

exports.deleteCurrentCampaign = catchAsync(async (req, res, next) => {
  await User.findByIdAndUpdate(req.campaign.id, { active: false });

  res.status(204).json({
    status: 'success',
    data: null
  });
});

campaignRoutes:

const router = express.Router();

router
  .route('/')
  .get(campaignController.getAllCampaigns)
  .post(
    authController.protect,
    authController.restrictTo('admin', 'super-admin'),
    campaignController.createCampaign
  );

router
  .route('/:id')
  .get(campaignController.getCampaign)
  .patch(
    authController.protect,
    authController.restrictTo('admin', 'super-admin'),
    campaignController.updateCampaign
  )
  .delete(
    authController.protect,
    authController.restrictTo('admin', 'super-admin'),
    campaignController.deleteCampaign
  );

module.exports = router;

Any idea where I am going wrong?


Solution

  • All code looks good but may be problem is,your collection not contain any records whose isDeleted=true.

    because "find query middleware" in campaignModel is called before any find* query and it find all document whose isDeleted != false.