MongoDB NestJS API dies if a #Prop is set to ObjectId - mongodb

So, when i set a #Prop() to ObjectId, the api wont start, but if i set it a string it loads up just fine.
Can you help me? Thanks!
Heres the error:
Schema:
import { Prop, Schema, SchemaFactory } from "#nestjs/mongoose";
import { Document, ObjectId } from "mongoose";
export type FriendRequestDocument = FriendRequest & Document;
#Schema({collection: "friendRequests"})
export class FriendRequest {
#Prop()
author: ObjectId;
#Prop()
friend_id: ObjectId;
#Prop()
request_at: Date;
}
export const FriendRequestSchema = SchemaFactory.createForClass(FriendRequest);
edit:
I figured it out!
import { Prop, Schema, SchemaFactory } from "#nestjs/mongoose";
import mongoose, { Document, ObjectId } from "mongoose";
export type FriendRequestDocument = FriendRequest & Document;
#Schema({collection: "friendRequests"})
export class FriendRequest {
#Prop()
author: mongoose.Types.ObjectId;
#Prop()
friend_id: mongoose.Types.ObjectId;
#Prop()
request_at: Date;
}
export const FriendRequestSchema = SchemaFactory.createForClass(FriendRequest);
I dont really know why its not working.

Related

Schema.name undefined while making Many-To-One relation reference with Nestjs & MongoDb

I want to attach and see all the posts of the user inside posts property of UserSchema. The user/Author id is getting stored with posts. But when I try the get posts ids
I'm getting the following error.
#Prop([{ type: mongoose.Schema.Types.ObjectId, ref: BlogPost.name }])
^
TypeError: Cannot read properties of undefined (reading 'name')
at Object.<anonymous> (D:\Noum\Data\CYBRNODE\MAN STACK\Cybrnode-Blog-Backend\Cybr-Blog-Nest-Backend\src\schema\user.schema.ts:45:64)
at Module._compile (node:internal/modules/cjs/loader:1126:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10)
at Module.load (node:internal/modules/cjs/loader:1004:32)
Blog Schema
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { ApiProperty } from '#nestjs/swagger';
import mongoose, { Document } from 'mongoose';
import { User } from 'src/schema/user.schema';
#Schema({ timestamps: true })
export class BlogPost {
#ApiProperty({ required: true })
#Prop({ type: mongoose.Schema.Types.ObjectId, ref: User.name })
author: User;
}
export const postSchema = SchemaFactory.createForClass(BlogPost);
export type postDocument = BlogPost & Document;
User Schema
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { ApiProperty } from '#nestjs/swagger';
import mongoose, { Document } from 'mongoose';
import { BlogPost } from 'src/schema/blog.schema';
#Schema({ timestamps: true })
export class User {
#ApiProperty()
#Prop([{ type: mongoose.Schema.Types.ObjectId, ref: BlogPost.name }])
posts: BlogPost[];
}
export const userSchema = SchemaFactory.createForClass(User);
export type userDocument = User & Document;
Also I've imported UserModule into BlogPostModule and vice versa. And exported the services of both modules.
I've tried with these as well. But Error is same
import { Document, Schema as MongooseSchema } from 'mongoose';
export class User extends Document{
#ApiProperty()
#Prop([{ type: MongooseSchema.Types.ObjectId, ref: BlogPost.name }])
posts: BlogPost[];
}
export const userSchema = SchemaFactory.createForClass(User);
export type userDocument = User & Document;

NestJS Mongoose schema definition

I have class, with nested object where I need only one field required and then all other keys are undefined and unlimited with string type, how could I write it in TypeScript?
I have tried this logic:
#Schema({ _id: false })
class Translations extends mongoose.Document {
#Prop({ required: true })
en: string;
#Prop()
[key: string]: string;
}
but mongoose complains about it
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { Document } from 'mongoose';
#Schema()
export class Translation {
#Prop({required: true})
en: string;
#Prop()
[key: string]: string;
}
export const TranslationSchema = SchemaFactory.createForClass(Translation);

How to populate Nestjs mongoose schema records

I want to get then enteries from paris air quality, but the thing is that the mongoose schema is nested and I tried to make multiple schemas separated but I don't know wheter it's correct or not.
This is the schema file schemas/air-quality.schema.ts
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { Document } from 'mongoose';
export type AirQualityDocument = AirQuality & Document;
#Schema()
export class Pollution {
#Prop()
ts: string;
#Prop()
aqius: number;
#Prop()
mainus: string;
#Prop()
aqicn: number;
#Prop()
maincn: string;
}
#Schema()
export class Result {
#Prop({ type: Pollution })
pollution: Pollution;
}
#Schema()
export class AirQuality {
#Prop({ type: Result })
result: Result;
#Prop()
datetime: string;
}
export const AirQualitySchema = SchemaFactory.createForClass(AirQuality);
And the result I am getting from mongo is this
PS: it contains multiple entries of the same schema
[
{
"_id": "62dd1b2e744e6bf8cdbcfabd",
"result": {
"_id": "62dd1b2e744e6bf8cdbcfabe"
},
"datetime": "24/07/2022, 11:13:02",
"__v": 0
},
...
]
I don't if the mistake is with the schema or I just need to use autopopulate or something

How to accept multiple objects into an array NestJS

I have a feedbackQuestion schema which takes (title: string, subtitle: string, types: enum, values: enum)
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose'
import { Document } from 'mongoose'
import { Types, Value } from 'src/common/enum/types.enum'
export type FeedbackQuestionDocument = FeedbackQuestion & Document
#Schema({ timestamps: true, id: true })
export class FeedbackQuestion {
#Prop()
title: string
#Prop()
subtitle: string
#Prop()
types: Types
#Prop()
value: Value
}
export const FeedbackQuestionSchema =
SchemaFactory.createForClass(FeedbackQuestion)
The feedbackQuestion schema serves as a subdocument in my feedback schema for the key question
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose'
import mongoose, { Document, ObjectId } from 'mongoose'
import { User } from './user.schema'
import { Transform, Type } from 'class-transformer'
import { FeedbackQuestion } from './feedback-question.schema'
import { distributionChannels } from 'src/common/enum/distributionChannels.enum'
export type FeedbackDocument = Feedback & Document
#Schema({ timestamps: true, id: true })
export class Feedback {
#Transform(({ value }) => value.toString())
_id: ObjectId
#Prop()
label: string
#Prop({ default: false })
status: boolean
#Prop()
question: [FeedbackQuestion]
#Prop()
comment: string
#Prop()
thankYouMessage: string
#Prop()
distributionChannels: distributionChannels
#Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'User' })
#Type(() => User)
user: User
}
export const FeedbackSchema = SchemaFactory.createForClass(Feedback)
when creating my create-feedbackDto, I assigned question to be an array of type feedbackQuestion
import { Type } from 'class-transformer'
import { FeedbackQuestion } from '../../schemas/feedback-question.schema'
import { IsArray, IsEnum, IsNotEmpty, ValidateNested } from 'class-validator'
import { Types, Value } from '../enum/types.enum'
import { distributionChannels } from '../enum/distributionChannels.enum'
export class CreateFeedbackDto {
#IsNotEmpty()
label: string
status: boolean
#IsArray()
#ValidateNested({ each: true })
#Type(() => FeedbackQuestion)
question: FeedbackQuestion[]
#IsNotEmpty()
comment: string
#IsNotEmpty()
thankYouMessage: string
#IsNotEmpty()
title: string
#IsNotEmpty()
subtitle: string
#IsEnum(Types)
#IsNotEmpty()
types: Types
#IsEnum(Value)
#IsNotEmpty()
value: Value
#IsEnum(distributionChannels)
#IsNotEmpty()
distributionChannels: distributionChannels
}
In my feedback services, I want to work on questions such that I can pass in multiple objects of feedbackQuestion into the question array when creating a feedback. Please How can I do that?
The current code only takes one FeedbackQuestion object in the array
import { Injectable } from '#nestjs/common'
import { InjectModel } from '#nestjs/mongoose'
import { Model } from 'mongoose'
import { Feedback, FeedbackDocument } from '../../schemas/feedback.schema'
import {
FeedbackQuestion,
FeedbackQuestionDocument,
} from '../../schemas/feedback-question.schema'
import { IServiceResponse } from '../../common/interfaces/service.interface'
import { CreateFeedbackDto } from 'src/common/dto/create-feedback.dto'
#Inject#5406able()
export class FeedbackService {
constructor(
#Inject#5406Model(Feedback.name)
private feedbackDocumentModel: Model<FeedbackDocument>,
#Inject#5406Model(FeedbackQuestion.name)
private feedbackQuestionDocumentModel: Model<FeedbackQuestionDocument>,
) {}
async createFeedback(payload: CreateFeedbackDto): Promise<IServiceResponse> {
const feedbackQuestion = await this.feedbackQuestionDocumentModel.create({
title: payload.title,
subtitle: payload.subtitle,
type: payload.types,
value: payload.value,
})
const feedback = await this.feedbackDocumentModel.create({
label: payload.label,
status: payload.status,
question: [feedbackQuestion],
comment: payload.comment,
thankYouMesage: payload.thankYouMessage,
distributionChannels: payload.distributionChannels,
})
// feedback.question.push(feedbackQuestion)
await feedback.save()
return {
data: {
user: feedback,
},
}
}
}
This is the current response I get
"label": "Yearly Feedback",
"status": false,
"question": [
{
"title": "Yearly Feedback",
"subtitle": "Rating the Yearly performance of the organization",
"value": 1,
"_id": "627fa9b915d31bbbc0fe6908",
"createdAt": "2022-05-14T13:08:09.180Z",
"updatedAt": "2022-05-14T13:08:09.180Z",
"__v": 0
}
],
Thanks

MissingSchemaError in Nestjs

hello everyone i'm not able specify relation to another model. when i add a relation it's showing me this error
Book Model
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { Document } from 'mongoose';
export type BookDocument = Book & Document;
#Schema({ timestamps: true, collection: 'books' })
export class Book {
#Prop({ type: String, required: true })
name: string;
#Prop({ type: String, required: true })
author: string;
#Prop({ type: String, required: true })
bookType: string;
}
export const BooksSchema = SchemaFactory.createForClass(Book);
BookLend Model
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { Schema as mongooseSchema, Document } from 'mongoose';
import { Book } from '../../books/enitiy/book.model';
import { IsNotEmpty } from 'class-validator';
export type BookLendDocument = BookLend & Document;
#Schema({ timestamps: true })
export class BookLend {
#IsNotEmpty()
#Prop({ type: mongooseSchema.Types.ObjectId, ref: 'books', required: true })
bookId: Book;
#IsNotEmpty()
#Prop({ type: String, required: true })
name: string;
#IsNotEmpty()
#Prop({ type: String, required: true })
returnDate: string;
#Prop({ type: String })
returnedOn: string;
#IsNotEmpty()
#Prop({ type: String, required: true })
status: string;
}
export const BookLendSchema = SchemaFactory.createForClass(BookLend);
i'm referring the books objectID to booklend booksID , when i use below code i'm getting error MissingSchemaError: Schema hasn't been registered for model "books".
const allBookLendDetails = await this.bookLend
.find()
.populate('bookId')
.exec();
hi guy's I fixed it by importing the BooksSchema into BookLend Module file
here ref code:-
import { Module } from '#nestjs/common';
import { BookLendService } from './book-lend.service';
import { BookLendController } from './book-lend.controller';
import { MongooseModule } from '#nestjs/mongoose';
import { BookLendSchema } from './entities/book-lend.entity';
import { CommonService } from '../common-service/common-service.service';
import { BooksSchema } from '../books/enitiy/book.model';
#Module({
imports: [
MongooseModule.forFeature([
{ name: 'booklend', schema: BookLendSchema },
{ name: 'books', schema: BooksSchema },
]),
],
controllers: [BookLendController],
providers: [BookLendService, CommonService],
})
export class BookLendModule {}
In the service file, you need to inject the model
constructor(
#InjectModel('booklend') private readonly bookLend: Model<BookLend>,
#InjectModel('books') private readonly books: Model<Book>
) {}