Home > Software engineering >  Solved - Mongoose and typescript how can i update the data?
Solved - Mongoose and typescript how can i update the data?

Time:07-23

I have an interface like this.

export interface IMerchant{
    id?:string,
    name:string,
    surname:string,
    mail:string,
}

My schema like this

    import { Schema, model, Model } from 'mongoose';

    interface IMerchantModel extends Model<IMerchant> {
        getAllMerchants(): IMerchant[];
        setMerchant(merchant:IMerchant):IMerchant;
    }
    
    const merchantSchema = new Schema<IMerchant, IMerchantModel>({
        name: { type: String, required: true },
        surname:{type:String,required:true},
        mail:{type:String,required:true},
    },
    {
        timestamps: { createdAt: "createdDate", updatedAt: "updatedDate" },
        toJSON: { virtuals: true },
    });

    const Merchant = model<IMerchant, IMerchantModel>('Merchant', merchantSchema);
    export default Merchant;

My main goal is create a data if not exist or update it if exist.

merchantSchema.static('setMerchant', async function setMerchant(merchant:IMerchant) {
    try{
        if(merchant.id){
            // if object has id field get from collection.
            let m = await this.findOne({ id: merchant.id }) as IMerchant;
            if (m) {
               m={...merchant};
               m.save();
               //Error -> Property 'save' does not exist on type 'IMerchant'.
            }
            return m;
        }
        else{
            // if not exist, create one
            const newData= new Merchant(merchant);
            const savedData=await newData.save();
            return savedData;
        }
    }
    catch(e){
        // throw an Error
    }
});

So main problem in update I got an error.

Property 'save' does not exist on type 'IMerchant'.

How can I cast return data from findOne

CodePudding user response:

According this documentation mongoose doesn't suggest extends Document.

Alternatively, your document interface can extend Mongoose's Document class.

We strongly recommend against using this approach, its support will be dropped in the next major version as it causes major performance issues. Many Mongoose TypeScript codebases use the below approach.

import { Document, Schema, model, connect } from 'mongoose';

interface IUser extends Document {
  name: string;
  email: string;
  avatar?: string;
}

Thus, HydratedDocument can be solution.

import { Schema, model, Model, HydratedDocument } from 'mongoose';

change from

let m = await this.findOne({ id: merchant.id }) as IMerchant;

to

let m = await this.findOne({ id: merchant.id }) as HydratedDocument<IMerchant>;
  • Related