szokodiakos / typegoose

Typegoose - Define Mongoose models using TypeScript classes.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Validation error: two classes with same name conflict

fabioformosa opened this issue · comments

Versions

  • NodeJS: 8.10.0
  • Typegoose(NPM): 5.9.0
  • mongoose: 5.6.8
  • mongodb: 3.2.3

Code Example

I have 3 classes (two of them with the same name Bar):

  • Bar with 3 fields (it has a Model) /src/model/bar/bar.ts
export default class Bar extends Typegoose {

  @prop({required : true})
  fieldOne: string;
  
  @prop()
  fieldTwo : string;

  @prop({required : true})
  fieldThree: string;

}

export const BarModel = new Bar().getModelForClass(Bar, {
  existingMongoose: mongoose,
  schemaOptions: { collection: 'BarCollection' },
});

NOTE: fieldTwo is not required!

  • Bar with 2 fields (it hasn't a model, it's embedded into Foo) /src/model/foo/bar.ts
export default class Bar {

  @prop({required: true})
  fieldOne: string;

  @prop({required : true})
  fieldTwo : string;

}

NOTE: fieldTwo is required!

  • Foo (has a Bar with 2 fields) /src/model/foo/foo.ts
import Bar from '/src/model/foo/bar.ts';

export default class Foo extends Typegoose {

  @prop()
  fieldOne : string;

  @prop({required:true, _id:false})
  bar : Bar;

}

export const FooModel = new Foo().getModelForClass(Foo, {
  existingMongoose: mongoose,
  schemaOptions: { collection: 'FooCollection' },
});

BEHAVIOUR
If I save a Foo (that has a Bar with 2 fields inside), it's OK!
If I save a Bar (with 3 fields), it's not OK because validation fails.

    const bar = new Bar();
    bar.fieldOne = 'john';
   /* I don't set fieldTwo (because it's not required in Bar (with 3 fields)**/
    bar.fieldThree = 'doe';
    const barModel = new BarModel(bar);
    return await barModel.save();

I got the following error:
[ValidationError: Bar validation failed: fieldTwo: Path fieldTwo is required.]

I don't expect any error, because the fieldTwo is not required in Bar with 3 fields.
It seems as typegoose applies the @prop of the other Bar class that has the same class name but fieldTwo is required.

Any help?

You can reproduce the error, following these steps:

  1. git clone https://github.com/fabioformosa/typegoose-validation-error.git
  2. npm test

It's a very simple project with NestJs Framework.

Do you know why it happenes?

no

currently classes with same name are not supported
when you want it to work, add an number after the name to make them diffrent

reason:
typegoose depends heavily on Class.name (constructor.name)

-> i will add an note to the documentation that this will not work

Ok thanks, a note into the documentation would have saved me a lot of time.

Is it in roadmap a support for classes with the same name?

Is it in roadmap a support for classes with the same name?

because typegoose depends so heavily on this structure, at least not until version 7.0.0, and currently i dont see another way of doing it with all the features that we have

What a pity!

I find this lib very useful and I would like to use it in my project, but there are a lot of classes with the same name.

I would try to add this feature on my own and submit a PR.
Could you give me some hint?

I'm thinking to add a new decorator on class: @Qualifier('classNameAlias').
If it's not provided, so the behaviour is 'as-is'.
It it's provided, typegoose uses it in place of actual class name.

In @prop it would need to add an attribute to refer the aliasType in place of actual Type prop(useQualifier: 'classNameAlias') .

So:

@Qualifier('Bar2')
class Bar {
 ...
}

class Foo extends Typegoose{
   @prop(typeQualifier: 'Bar2')
   Bar bar;

}

What do you think about?

I would try to add this feature on my own and submit a PR.

when you try this, please target it on the r6/master branch (in my fork, because i dont have write permissing yet here (original author abandonded it))


Could you give me some hint?

first look on how typegoose works, and then especially on how it stores names (example: Map<name, schema>)


@Qualifier('classNameAlias')

try to use the existing @modelOptions({})

when you try this, please target it on the r6/master branch (in my fork, because i dont have write permissing yet here (original author abandonded it))

It's not clear to me.
If it's allowed to you to modify the doc adding the alert about class name clashing, why can't you write as well that this project is abandonated and redirect people to your active fork?

If it's allowed to you to modify the doc adding the alert about class name clashing, why can't you write as well that this project is abandonated and redirect people to your active fork?

look at typegoose/typegoose#1 currently @Ben305 is the active maintainer but is currently (one week) not here, and in the mean time i modified my fork with everything needed (github pages (if pushed to master), labels, auto-deploy)


If it's allowed to you to modify the doc adding the alert about class name clashing

i need to make a pull request until typegoose/typegoose#1 or i get a maintainer of this ( #99 )