Search code examples
mongodbtypescriptmongoosetypegoose

Hooks are not working on updateOne when using Typegoose only for save operations are called


I've already created this and been using this Model. But now I've added @pre<Offer>("save" as i want to do a few checks to the data before saving and adjust the values accordingly.

My problem is that when i do an update first the console logs never get output. Then I can't ever set this.isOfferLive = false; if i post isOfferLive:true so the pre is never called

What am i missing you?

I am using

    "reflect-metadata": "^0.1.13",
    "typegoose": "^5.7.2",
    "mongoose": "^5.6.3",
emitDecoratorMetadata and experimentalDecorators are be enabled in tsconfig.json

One thing I noticed is that the hooks get called on Model.create but not on Model.updateOne when looking at the consoe logs.

How do i make them also work on Update

My class

@pre<Offer>("save", function(next: HookNextFunction) {
  console.log("[**** save]: " + this.isOfferLive);
  this.isOfferLive = false;
  if (!isOfferValid(this)) {
    this.isOfferLive = false;
  }
  next();
})
export class Offer extends Typegoose {
  @prop({ required: true, default: false })
  public isOfferLive: boolean;
}

export const Model = new Offer().getModelForClass(Offer);

Solution

  • Update: Found a way to update it, but its not documented & i dont recommend it!:

    import * as mongoose from "mongoose";
    import { pre, prop, Typegoose } from "./typegoose/src/typegoose";
    
    @pre<Offer>("updateOne", function(this: mongoose.Query<any>) {
        // @ts-ignore
        this._update.isOfferLive = true;
        return;
    })
    class Offer extends Typegoose {
        @prop({ required: true, default: false })
        public isOfferLive: boolean;
    }
    const OfferModel = new Offer().getModelForClass(Offer);
    
    (async () => {
        mongoose.set("debug", true);
        await mongoose.connect(`mongodb://mongodb:27017/`, {
            useNewUrlParser: true,
            useFindAndModify: true,
            useCreateIndex: true,
            dbName: "verify315",
            user: "user",
            pass: "passwd",
            authSource: "admin",
            autoIndex: true
        });
    
        const dummy = new OfferModel();
        await dummy.save();
    
        await dummy.updateOne(dummy).exec();
    
        const dummyback = await OfferModel.findById(dummy._id).exec(); // re-fetch because otherwise it does not load the changes
        console.log("after updateOne:", dummyback);
    
        await mongoose.disconnect();
    })();