1

I use this schema of addresses and use it in several schemas. All works fine, only when I update a address

const addressSchema = new mongoose.Schema({
    street: String,
    number: String,
    postcode: String,
    city: String,
    comment: String,
    country: {
        type: 'ObjectId',
        ref: 'Country'
    },
    location: {
        type: pointSchema,
        default: () => ({}),
        index: '2dsphere',
    }
});

addressSchema.pre('save', async function (next) {
    console.log('subdocument address pre.save'); // is triggred
    //create geolocation
});


addressSchema.pre('updateOne', async function (next) {
    console.log('subdocument address pre.updateOne'); // not triggred, no error
    //update geolocation
});

Mongoose's documation speak only about middelware save and validate.

https://mongoosejs.com/docs/subdocs.html#what-is-a-subdocument-

But what is the best solution to do what I want ?


Additional informations

const pointSchema = new mongoose.Schema({
    type: {
        type: String,
        enum: ['Point'],
        default: 'Point'
    },
    coordinates: {
        type: [Number],
        default: null,
    }
});
const common = require('./common');
const customerSchema = new Schema({
    //...
   address: {
        type: common.addressSchema,
        default: () => ({}),
    },
})

const providerSchema = new Schema({
    //...
   address: {
        type: common.addressSchema,
        default: () => ({}),
    },
})
    "address": {
        "_id": "6043a5f3a8cad615cd8eab3a",
        "location": {
            "type": "Point",
            "coordinates": [
                48.818511962890625,
                2.31961989402771
            ],
            "_id": "603fed0629390b30d53bed3e"
        },
        "street": "Avenue des Tulipes",
        "postcode": "78500",
        "number": "69",
        "city": "Montrouge",
        "comment": null,
        "country": "5f626eb337fd4d75ab694112"
    },

When we create a new customer we have no problem with addressSchema's middleware 'save', but when we update a Customer, all datas are updated correctly, but the addressSchema's middleware 'updateOne' isn't triggered.

Rifton007
  • 291
  • 1
  • 5
  • 24
  • can you post pointSchema and your update query that is not triggering in middleware. – turivishal Mar 06 '21 at 15:24
  • is this address schema, child of customer schema? if it is then please specify in your question. and also it will helpful if you post your update query as well. – turivishal Mar 07 '21 at 10:04
  • it's a child of several schemas, it's used for each schema wich have addresse – Rifton007 Mar 07 '21 at 12:17

1 Answers1

0

I am not sure is there any straight way to do this, but you can create pre midddlewares for your all parent schemas customerSchema and providerSchema and put condition like is address updated or not,

  • create a function to handle operation on address schema if its in update
function preHookForAddress (_this) {
   // if its "address" object
   if (_this.get('address')) {
        let address = _this.get('address');
        // operation stuff here
        // ..
        // set after update
        _this.set({ address: address });
   }

   // if its "address.location" object
   if (_this.get('address.location')) {
        let address_location = _this.get('address.location');
        // operation stuff here
        // ..
        // set after update
        _this.set({ "address.location": address_location });
   }
}

customerSchema.pre('updateOne', async function (next) {
    await preHookForAddress(this);
    next();
});

providerSchema.pre('updateOne', async function (next) {
    await preHookForAddress(this);
    next();
});
turivishal
  • 34,368
  • 7
  • 36
  • 59