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?
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.