Nar
Nar

Reputation: 137

Mongoose: .findById is not a function

I have 2 different models User and Leave, I wanted to set it up so that whenever a leave is deleted, that leave will also be pulled from an array of leaves in the User document.

User model:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const muv = require('mongoose-unique-validator');
const Leave = require('./leave');
const { ObjectID } = require('mongodb');

var schema = new Schema({
  fullName: {
    type: String,
    required: true,
    unique: true
  },
  leaveCredits: {
    type: Number
  },
  filedLeaves: [{
    type: Schema.Types.ObjectId,
    ref: 'Leave'
  }]
}, {
  usePushEach: true
});

schema.plugin(muv);

schema.pre('remove', function (next) {
  let user = this;
  let toDelete = [];
  user.filedLeaves.forEach(function(item) {
    Leave.findByIdAndRemove(new ObjectID(item), (err, succ) => {
      if (succ) {
        console.log(`${item} Deleted`);
      }
    });
  });
  next();
});

module.exports = mongoose.model('User', schema);

Leave model:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const User = require('../models/user');
const { ObjectID } = require('mongodb');

var schema = new Schema({
  userId: {
    type: Schema.Types.ObjectId,
    ref: 'User'
  },
  status: {
    type: String,
    required: true
  },
  start: {
    type: String,
    required: true
  },
  end: {
    type: String,
    required: true
  },
  type: {
    type: String,
    required: true
  }
});

// makes sure that the removed date is also removed from the User's leave array
schema.pre('remove', function (next) {
  let leave = this;
  User.findById(new ObjectID(leave.userId), function (err, user) {
    user.filedLeaves.pull(leave._id);
    user.save();
  });
  next();
});

module.exports = mongoose.model('Leave', schema);

It keeps giving me an error the User.findById is not a function but I'm pretty sure I've exported both properly as models since my whole app works aside from this minor problem I have right now.

Tried googling around but none of the stuff I saw has helped me resolve this.

EDIT: Tried using just find() but still throwing the same error that it isn't a function.

Upvotes: 4

Views: 3464

Answers (1)

Orelsanpls
Orelsanpls

Reputation: 23495

The problem you have is that both your schema require the other one to work. This is a circular require problem.

To make it work you can use a fix like :

// makes sure that the removed date is also removed from the User's leave array
schema.pre('remove', function (next) {
  const User = require('../models/user');  

  let leave = this;

  User.findById(new ObjectID(leave.userId), function (err, user) {
    user.filedLeaves.pull(leave._id);
    user.save();
  });
  next();
});

schema.pre('remove', function (next) {
  const Leave = require('./leave');

  let user = this;
  let toDelete = [];

  user.filedLeaves.forEach(function(item) {
    Leave.findByIdAndRemove(new ObjectID(item), (err, succ) => {
      if (succ) {
        console.log(`${item} Deleted`);
      }
    });
  });
  next();
});

We are making the require only when the pre get called. Which avoid the circularity problem.

Upvotes: 6

Related Questions