Closed YussufElarif closed 5 years ago
What I do normally in mongoose is:
import { Schema, model } from 'mongoose'; const SubCategorySchema = new Schema({ value: { type: String } }) const CategorySchema = new Schema({ value: { type: String, required: true }, subCategories: [SubCategorySchema] }); SubCategorySchema.set('toJSON', { virtuals: true, versionKey: false, transform: (doc, ret, options) => { delete ret._id; return ret; } }) CategorySchema.set('toJSON', { virtuals: true, versionKey: false, transform: (doc, ret, options) => { delete ret._id; return ret; } }); export const Category = model('Category', CategorySchema);
When the data comes through express and into my web app. The application prints the
id
rather than the_id
for bothCategorySchema
andSubCategorySchema
which is what I want. However, I can't seem to replicate this on typegoose. I can only manage to do it forCategory
by doing this:import { Typegoose, prop, arrayProp } from 'typegoose'; import { ICategory, ISubCategory } from './category.interface'; export class SubCategory implements ISubCategory { readonly id: string; @prop({ required: true }) public value: string; } export class Category extends Typegoose implements ICategory { readonly id: string; @prop({ required: true }) public value: string; @arrayProp({ items: SubCategory, _id: false }) public subCategories?: SubCategory[]; } export const CategoryContext = new Category().getModelForClass(Category, { schemaOptions: { toJSON: { virtuals: true, versionKey: false, transform: (doc, ret, options) => { delete ret._id; return ret; } } } });
Is this feature not implemented or have i missed it out from the docs? What other alternatives are there for this?
you can try to use this package
@aoi-umi I've reverted back to mongoose. I'll have a try at that package later on. Thanks :)
I had a similar case. I thought I could call setModelForClass
on the child schema and pass schema options to it (according to the docs, it would overwrite the existing model for the child schema). I wonder why this doesn't work.
schemaOptions
work for the top level doc only. When I queried the whole thing with embedded docs, schemaOptions like _id: false
does not apply to the returned children object. This happens EVEN IF I set schemaOptions for the embedded schema
@hasezoey do you mind looking into this? Since, schemaOptions don't apply, I can't fetch virtual props of embedded docs either.
@ObjectType()
export class Boardextends Typegoose {
@Field(type => [Square])
@arrayProp({ items: Square, default: DEFAULT_BOARD })
squares: Square[];
}
export const BoardModel = new Board().getModelForClass(Board, {
schemaOptions: {
_id: false,
toJSON: { virtuals: true },
toObject: { virtuals: true }
}
});
@ObjectType()
export class Square extends Typegoose {
@Field(type => File)
@prop({ enum: File, required: true })
file: File;
@Field(type => Int)
@prop({ required: true })
rank: number;
@instanceMethod // tried putting this as prop, works only for top-level returned doc. If Square is a child of something, it doesn't have "name" prop
get name(this: InstanceType<Square>): string {
// it's stored as a number so should return the letter
return `${File[this.file]}${this.rank}`;
}
}
export const SquareModel = new Square().getModelForClass(Square, {
schemaOptions: {
_id: false,
toJSON: { virtuals: true },
toObject: { virtuals: true }
}
});
@Drageaux first some things before i can answer: what is(when from typegoose, the imports would be good to know) @Field
, @ObjectType
, and what from these two do you want to embed | what is child, what is parent?
otherwise, i dont know what you mean, i have an example below, and it just works:
import * as mongoose from "mongoose";
import { instanceMethod, prop, Typegoose } from "typegoose";
class Dummy extends Typegoose {
@prop({ required: true, default: "hello" })
public name!: string;
@instanceMethod
public hello(...args: any[]) {
console.log("Dummy hello");
}
}
class DummyParent extends Typegoose {
@prop({ required: true, default: "nothello" })
public anothername!: string;
@prop({ required: true })
public dummy!: Dummy;
@instanceMethod
public somehello(...args: any[]) {
console.log("DummyParent somehello");
}
}
const DummyModel = new Dummy().getModelForClass(Dummy);
const DummyParentModel = new DummyParent().getModelForClass(DummyParent);
(async () => {
mongoose.set("debug", true);
await mongoose.connect(`mongodb://mongodb:27017/`, {
useNewUrlParser: true,
useFindAndModify: true,
useCreateIndex: true,
dbName: "verify227Drageaux",
user: "user",
pass: "passwd",
authSource: "admin",
autoIndex: true
});
const newdm = new DummyModel();
newdm.hello();
const newdpm = new DummyParentModel({dummy: newdm});
newdpm.somehello();
newdpm.dummy.hello();
await mongoose.disconnect();
})();
(output from it:)
Dummy hello
DummyParent somehello
Dummy hello
Anyone found a solution on this ? I'm having the same issue (sub-document with _id
that I want to transform to id
) :/
@diephil would #331 help?
Hello @hasezoey , I finally found a workaround for my issue.
In a context of an REST API endpoint (with NestJS), I'm calling a parentSchema.toJSON()
before sending back my nested entities to the client.
The toJSON
method searches deeply and replace all _id
properties with id
. Thank you for your suggestion
schemaOptions for embedded schemas
this should work in 6.0.0 (not tested yet), thanks to @modelOptions
this can be closed because it is included in v6.0.0 (to an extend)
@Ben305
What I do normally in mongoose is:
When the data comes through express and into my web app. The application prints the
id
rather than the_id
for bothCategorySchema
andSubCategorySchema
which is what I want. However, I can't seem to replicate this on typegoose. I can only manage to do it forCategory
by doing this:Is this feature not implemented or have i missed it out from the docs? What other alternatives are there for this?
Stackoverflow link: https://stackoverflow.com/questions/53696331/schemaoptions-for-embedded-models-typegoose