Typegoose binding referernce to polymorphic model - mongodb

I have a situation with polymorphic models
interface IEvent {
title: string;
}
class SubscribeEvent implements IEvent {
#prop()
title: string;
#prop({ref: User})
user: IUser;
}
class NewsEvent implements IEvent {
#prop()
title: string;
#prop({ref: Post})
post: IPost;
#prop({ref: User})
user: IUser;
}
class OrderEvent implements IEvent {
#prop()
title: string;
#prop({ref: Order})
order: IOrder;
}
Now I created a typegoose model:
class Card extends Typegoose {
#prop()
name: string;
#prop()
events: IEvent[];
}
How do I correctly map and extract the Card instance with populated references?

Related

Nest.js, Graphql, Typeorm, Postgres mutations

I`m a newbee at this technologies and I literally dont understand how to do task. My task: create 2 tables, for categories and tasks, after that create mutation for creating category and tasks(todos).
mutation {
createTodo(input: {
categoryName: “”,
text: “”
}) {
category: {
id
title
}
id
text
isCompleted
}
}
I created objectTypes and input types, but I dont understand how to create such mutation. Example objectTypes and Inputs
#ObjectType()
export class CategoryType {
#Field(() => ID)
id: number
#Field(() => String)
readonly title: string
}
export interface TodoI {
id: number;
text: string;
isCompleted: boolean;
categoryId: number
category: any;
}
#InputType()
export class CategoryInput {
#Field()
readonly title: string
#Field(() => TodoInput,{nullable: true})
readonly todos: TodoI
}
#ObjectType()
export class TodoType {
#Field(() => ID)
id: number
#Field()
readonly text: string
#Field()
readonly isCompleted: boolean
#Field(() => Int)
readonly categoryId: number
}
#InputType()
export class TodoInput {
#Field()
readonly text: string;
#Field()
readonly isCompleted: boolean;
#Field(() => Int)
readonly categoryId: number;
}

Add a new field to the Typegoose subdocument

How do I include an extra field in the User class subdocument?
class Car {
#prop()
public model?: string;
}
class User {
#prop()
public name?: string;
#prop({ required: true })
public age!: number;
#prop({ ref: () => Car })
public cars?: Ref<Car>[];
}
Populated Car Collection:
Car A
{
"_id": "1"
"model": "Ferrari"
}
Car B
{
"_id": "2"
"model": "Tesla"
}
User collection populated according to the default class:
User
{
"_id": "1",
"name": "Jonh Doe",
"age": 25,
"cars": [
{ "_id": "1" },
{ "_id": "2" }
]
}
I need to include a "status" field in the cars array of the User collection, as shown below:
status is to identify whether the car model is active for the user
User
{
"_id": "1",
"name": "Jonh Doe",
"age": 25,
"cars": [
{ "_id": "1", "status": false },
{ "_id": "2", "status": true }
]
}
Hasezoey helped me with the github issue.
Here's the link and his answer.
https://github.com/typegoose/typegoose/discussions/726
You have multiple options:
make the current reference array a subdocumentarray (see example 1)
include the status property on the car itself
have a separate class that has a unique compound index on the user-car references and has the properties you want and have such a reference field in the user (either through virtual populate or with a explicit ref array) (see example 2)
Example 1:
class Car {
#prop()
public model?: string;
}
class UserCarSub {
#prop({ ref: () => Car })
public car: Ref<Car>;
#prop()
public extra_properties: string;
}
class User {
#prop()
public name?: string;
#prop({ required: true })
public age!: number;
#prop()
public cars?: UserCarSub[];
}
Example 2:
// the first example does not use virtual populate
class Car {
#prop()
public model?: string;
}
class UserCarProperties {
#prop({ ref: () => Car })
public car: Ref<Car>;
#prop({ ref: () => User })
public user: Ref<User>;
#prop()
public extra_properties: string;
}
class User {
#prop()
public name?: string;
#prop({ required: true })
public age!: number;
#prop({ ref: () => Car })
public cars?: Ref<Car>[];
#prop({ ref: () => UserCarProperties })
public car_properties: Ref<UserCarProperties>[];
}
// the following uses virtual populate
class User {
#prop()
public name?: string;
#prop({ required: true })
public age!: number;
#prop({ ref: () => Car })
public cars?: Ref<Car>[];
#prop({ ref: () => UserCarProperties, foreignField: 'user', localField: '_id' })
public car_properties: Ref<UserCarProperties>[]; // this property does not exist in the database, but can still populate
}
Virtual Populate
Alternatively you could also in Example 2 merge the cars references into the UserCarProperties and use that to find cars, that is fully up to how you want it
Personally i would suggest Example 2 with virtual populate (merged) if the array is of unknown length or could grow to unknown length

Flutter Ferry Graphql pointing to the Entitiy not the dto

I have an entity is Nestjs
#Entity({ name: 'recipes' })
#ObjectType()
export class Recipe {
#PrimaryGeneratedColumn()
#Field(() => Int)
id: number;
#Column()
#Field()
videoUrl: string;
#Column()
#Field()
description: string;
}
I also have a create recipe dto
#InputType()
export class CreateRecipeInput {
#Field()
videoUrl: string;
#Field()
description: string;
#Field(() => [String])
ingredientNames: string[];
#Field(() => [String])
instructionNames: string[];
}
in my ferry Graphql I have this
mutation CreateRecipe($createRecipeInput: CreateRecipeInput!) {
createRecipe(createRecipeInput: $createRecipeInput) {
videoUrl
description
ingredientNames
}
}
The problem I have is if I get an error in the property ingredientNames, but if I add that property to the Recipe entity it works. It's like Ferry is not following the Recipe Dto. When I look at the schema.graphql is flutter The create recipe Dto is there.
input CreateRecipeInput {
videoUrl: String!
description: String!
ingredientNames: [String!]!
instructionNames: [String!]!
}

How to set up Unique Compound Index in NestJS (MongoDB)

Hey i have a schema for user with an unique email:
#Schema()
export class User {
#Prop()
firstName!: string;
#Prop()
lastName!: string;
#Prop({
unique: true,
})
email!: string;
#Prop({ nullable: true })
password?: string;
}
But now i want to extend this. I wanna have Groups with their own users. I would create a collection of groups and add their id to the users like:
#Schema()
export class User {
#Prop()
groupId: string;
#Prop()
firstName!: string;
...
}
For each group the email should be unique. That means in the collection of users there could be duplicate emails but they should be unique by group which is named Unique Compound Index i guess.
How do i set this up in NestJS?
Looks like its not possible to achieve it solely by use of the #nestjs/mongoose decorators, however its possible to declare index by use of SchemaFactory
#Schema()
export class User {
#Prop()
groupId: string;
#Prop()
firstName!: string;
...
}
export const UserSchema = SchemaFactory.createForClass(User);
UserSchema.index({ groupId: 1, firstName: 1 }, { unique: true });
Then you must do either create migration to create this index or enable auto-index feature
#Schema({
autoIndex: true, // <--
})
export class User {
#Prop()
groupId: string;
#Prop()
firstName!: string;
...
}

Angular 6 Observable Http get async

i'm newbie at angular and i have problem with get async data from http client, my code:
User Service:
getAll(): Observable<User[]> {
return this.http.get<User[]>(`${this.API_URL}/users`);
}
registerUser(user: User) {
return this.http.post(`${this.API_URL}/api/auth/registerUser`, user);
}
User model:
export class User {
id: number;
name: string;
username: string;
surname: string;
email: string;
password: string;
street: string;
numberStreet: string;
postalCode: string;
city: string;
}
User-list component:
export class UserListComponent implements OnInit {
public data: User[];
constructor(private userService: UserService, private modalService: NgbModal) {
}
ngOnInit() {
this.getListUsers();
}
getListUsers() {
this.userService.getAll().subscribe(
restItems => {
this.data = restItems;
}
);
}
this.userService.registerUser(this.registerForm.value)
}
and now if i add user and send post in database user is stored, but on front it doesnt come up. After reload page list of users working