Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Usage with TypeScript and typegoose #83

Closed
dandv opened this issue Apr 14, 2020 · 10 comments
Closed

Usage with TypeScript and typegoose #83

dandv opened this issue Apr 14, 2020 · 10 comments

Comments

@dandv
Copy link
Contributor

dandv commented Apr 14, 2020

I'm trying to use the plugin with typegoose, but I'm not sure if I need to supply the connection, at what point, how, and how to import properly using TypeScript.

Here's what I have:

import mongoose from 'mongoose';
import typegoose from '@typegoose/typegoose';
const { prop, getModelForClass, defaultClasses, plugin } = typegoose;
// Is this import right?
import AutoIncrement from 'mongoose-sequence'; AutoIncrement(mongoose);

@plugin(AutoIncrement, { inc_field: 'id', start_seq: 200 })
export class Foo extends defaultClasses.TimeStamps {
  ...
}
...
export const FooModel = getModelForClass(Foo);
...
mongoose.connect(mongoUrl, { ... });

The error I get comes from the getModelForClass line:

Please, pass mongoose while requiring mongoose-sequence: https://github.com/ramiel/mongoose-sequence#requiring

I understand why the connection is needed, but in classes of this sort, I'd like to only define the class and the model, and initialize the plugin later, when the script starts. Would this deferred initialization be possible? Ideally until the first insertion, but if not, just after defining the models.

If not possible, what do I need to pass to the plugin or typegoose?

Thanks!

CC @typegoose / @hasezoey

@ramiel
Copy link
Owner

ramiel commented Apr 14, 2020

You have to use the instantiation. Try to change your code like this

import mongoose from 'mongoose';
import typegoose from '@typegoose/typegoose';
const { prop, getModelForClass, defaultClasses, plugin } = typegoose;
// Is this import right?
import AutoIncrementFactory from 'mongoose-sequence'; 

// AutoIncrement now is the instance
const AutoIncrement = AutoIncrementFactory(mongoose);

@plugin(AutoIncrement, { inc_field: 'id', start_seq: 200 })
export class Foo extends defaultClasses.TimeStamps {
  ...
}
...
export const FooModel = getModelForClass(Foo);
...
mongoose.connect(mongoUrl, { ... });

To answer this question

Would this deferred initialization be possible? Ideally until the first insertion, but if not, just after defining the models.

Yes, sure, just call

const AutoIncrement = AutoIncrementFactory(mongoose);

after you initialized your models, but since the plugin, in mongoose, must be instantiated alongside model definition, I don't get your point.
I guess you can also wait for first insertion, but what would be the benefit?

@dandv
Copy link
Contributor Author

dandv commented Apr 15, 2020

Thanks @ramiel, that worked and I've added an example to the typegoose docs.

@ramiel
Copy link
Owner

ramiel commented Apr 15, 2020

Cool!

@ramiel ramiel closed this as completed Apr 15, 2020
@alimoli
Copy link

alimoli commented Jan 25, 2022

How is it possible to use setNext method in this Typescript solution?
In my case, the setNext is undefined on the object returned by model.FindOne.

@alimoli
Copy link

alimoli commented Jan 25, 2022

Moreover, any idea?

Screenshot 2022-01-25 at 15 55 16

Screenshot 2022-01-25 at 16 03 46

"mongoose": "^6.1.8"
"mongoose-sequence": "^5.3.0"
"@types/mongoose": "^5.11.97"
"@types/mongoose-sequence": "^3.0.6"

@hasezoey
Copy link

@alimoli from what i can tell, you are using the wrong function, see Requiring
in your case you would need AutoIncrement, but are using AutoIncrementFactory which expects a connection

also, you have @types/mongoose installed, which is now a stub package, because mongoose started shipping its own types

@alimoli
Copy link

alimoli commented Jan 26, 2022

Awesome thank you @hasezoey ! :D
It seems working correctly now.
Just the last question: do you know how to load this plugin just once using typegoose decorator?
I get the following error:
Error: Counter already defined for field "xxx"

@hasezoey
Copy link

Just the last question: do you know how to load this plugin just once using typegoose decorator?

typegoose (at least assuming you run the current latest version (9.5.0)), it does not automatically run plugins, but they are run by mongoose - and mongoose should only call plugins when specific events happen (like .save), but the plugin will need to handle being called multiple times from there

TL;DR: i dont know enough about mongoose-sequence to help with that, but typegoose should not be calling plugins

@cityvoice
Copy link

Moreover, any idea?

Screenshot 2022-01-25 at 15 55 16 Screenshot 2022-01-25 at 16 03 46
"mongoose": "^6.1.8"
"mongoose-sequence": "^5.3.0"
"@types/mongoose": "^5.11.97"
"@types/mongoose-sequence": "^3.0.6"

hi, I have this problem to.
I use mongoose-sequence for my schema in my nestjs project, this is my module.

import { Module } from '@nestjs/common';
import { MongooseModule, getConnectionToken } from '@nestjs/mongoose';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { User, UserSchema } from './schema/user.schema';
import * as AutoIncrementFactory from 'mongoose-sequence';
import { Connection } from 'mongoose';
import { DATABASE_CARGO } from '../constants';

@Module({
  imports: [
    MongooseModule.forFeatureAsync(
      [
        {
          name: User.name,
          //schema: UserSchema,
          useFactory: async (connection: Connection) => {
            const schema = UserSchema;
            const AutoIncrement = AutoIncrementFactory(connection);
            schema.plugin(AutoIncrement, {
              inc_field: 'userId',
              id: 'user',
            });
            schema.pre('save', (next) => {
              next();
            });
            schema.post(['findOne', 'find'], (docs) => {
              console.log(docs);
            });
            return schema;
          },
          inject: [getConnectionToken(DATABASE_CARGO)],
        },
      ],
      DATABASE_CARGO,
    ),
  ],
  controllers: [UserController],
  providers: [UserService],
  exports: [UserService],
})
export class UserModule {}

@type checks failed, it throws the exception:

src/user/user.module.ts:17:54 - error TS2345: Argument of type 'Connection' is not assignable to parameter of type 'Schema<any, Model<any, any, any, any, any>, {}, {}, {}, {}, DefaultSchemaOptions, { [x: string]: any; }>'.
  Type 'Connection' is missing the following properties from type 'Schema<any, Model<any, any, any, any, any>, {}, {}, {}, {}, DefaultSchemaOptions, { [x: string]: any; }>': add, alias, childSchemas, clearIndexes, and 24 more.

17           const AutoIncrement = AutoIncrementFactory(connection);
                                                        ~~~~~~~~~~

src/user/user.module.ts:18:25 - error TS2345: Argument of type 'void' is not assignable to parameter of type 'PluginFunction<User, Model<User, any, any, any, any>, any, any, any, any>'.

18           schema.plugin(AutoIncrement, { inc_field: 'users' });

now I have to changed the code to:

            const AutoIncrement = AutoIncrementFactory(
              connection as any,
            ) as any;

any idea?

@hasezoey
Copy link

hasezoey commented Feb 8, 2023

@cityvoice

it seems like the current types for this package (@types/mongoose-sequence) seem to have different types than are documented in the README, see L36 or the documentation is wrong

(as i can see you already filed a bug at DefinitelyTyped/DefinitelyTyped#64251)

in case it works for your workflow, there is also the alternative of @typegoose/auto-increment which was created because mongoose-sequence didnt work well with typescript or typegoose (it works without typegoose itself)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants