I have this Schema
const TransportSchema = new mongoose.Schema({
id: {
type: String,
require: true,
unique: true,
index: true
},
driver: {
_id: mongoose.Schema.Types.ObjectId,
username: String,
registrationId: String,
name: String
}
})
When I update the document using "updateOne" and a driver object like this:
import { v4 as uuidv4 } from 'uuid';
export default class User {
public readonly id: String;
public registrationId: String;
public name: String;
public username: String;
public role: String;
public passwordHash: String;
public createdAt: Date;
constructor(props: Omit<User, 'id'>, id?: String) {
Object.assign(this, props);
if(!id) {
this.id = uuidv4();
} else {
this.id = id;
}
}
}
async assignDriver(id: String, driver: User): Promise<boolean> {
const result = await MongoTransportModel.updateOne(
{ id },
{ driver, driverAssignedAt: Date.now() }
);
return !!result.nModified;
}
I don't want it to save the fields I haven't declared in the schema like "passwordHash", and it is saving. I tried to use strict: true and doesn't work.
Related
I'm trying to make API orders. The problem appears when I want to display all orders from the database using the GET method, but I get a 500 error and a message
CastError: Cast to ObjectId failed for value "order" (type string) at path "_id" for model "Product"
order.schemas.ts
#Schema()
export class Order {
#Prop()
username: string;
#Prop()
phone: string;
#Prop()
email: string;
#Prop()
adr: string;
#Prop({type: [{type: mongoose.Schema.Types.ObjectId, ref: 'Product'}]})
products_id: Product[];
}
product.schema.ts
#Schema()
export class Product {
#Prop()
name: string;
#Prop()
catalog_number: string;
#Prop()
old_price: number;
#Prop()
price: number;
#Prop()
desc_text: string;
#Prop()
desc_short: string;
#Prop()
image: string;
#Prop({type: [{type: mongoose.Schema.Types.ObjectId, ref: 'Order'}]})
orders: Order[];
}
This is file order.controller
#Controller('/order')
export class OrderController {
constructor(private orderServise: OrderService) { }
#Post()
create_order(#Body() dto: CreateOrderDto) {
return this.orderServise.create_order(dto);
}
#Get()
get_All() {
return this.orderServise.get_All();
}
#Get(':id')
getOne(#Param('id') id: ObjectId) {
return this.orderServise.getOne(id);
}
#Delete(':id')
delete(#Param('id') id: ObjectId) {
return this.orderServise.delete(id);
}
}
This is file order.service
#Injectable()
export class OrderService {
constructor(#InjectModel(Product.name) private productModule: Model<ProductDocument>,
#InjectModel(Order.name) private orderModule: Model<OrderDocument>) {}
async create_order (dto: CreateOrderDto): Promise<Order> {
const order = await this.orderModule.create({...dto });
return order;
}
async get_All(): Promise<Order[]> {
const order = await this.orderModule.find()
return order;
}
async getOne(id: ObjectId): Promise<Order>{
const order = await this.orderModule.findById(id).populate('products_id');
return order;
}
async delete(id: ObjectId): Promise<Order>{
const order = await this.orderModule.findOneAndDelete(id);
return order._id;
}
}
Что может быть не так? Потратил кучу времени на это!
I trying to take back my TelegramEntity from MongoDB and can't retrieve array with adverts. What can I do to fix this problem?
telegram.entity.ts:
import { prop, getModelForClass, modelOptions } from "#typegoose/typegoose";
export class AdvertSubscriptionEntity {
#prop({ type: String, required: true, select: true })
public location!: string;
#prop({ type: Boolean })
public lessOrEqual?: boolean;
#prop({ type: Number })
public price?: number;
#prop({ type: Boolean, default: true })
public active?: boolean;
constructor(opts?: Partial<AdvertSubscriptionEntity>) {
if (opts) {
Object.assign(this, opts);
}
}
}
#modelOptions({ schemaOptions: { collection: "telegrams" } })
export class TelegramEntity {
#prop({ type: String })
public username?: string;
#prop({ type: Number, required: true })
public chatId!: number;
#prop({
type: () => [AdvertSubscriptionEntity],
_id: false,
select: true
})
public adverts?: AdvertSubscriptionEntity[];
}
export const TelegramModel = getModelForClass(TelegramEntity);
Here is how I find my tg row:
return await TelegramModel
.findOne(filter, undefined, options)
.exec();
So in result: {"_id":"<ObjectId>","username":"<username>","chatId": <id> ,"__v":0}
My package.json:
"#typegoose/typegoose": "8.2",
"mongoose": "6",
I change adverts type from [AdvertSubscriptionEntity] to mongoose.Schema.Types.Mixed and my code works.
I am working on Nest.js CRUD. Every other component is working fine but the update throws a validation error when I try to update a field saying the other fields cannot be left empty. I tried to fix this from the service file but I am still getting the validation error. I tried my best to tweak it in different ways but nothing is happening. Below is what I have been able to come up with. I do not know what I am doing wrong.
account.repository.ts
async updateAccount(
id: string,
updateAccountDto: UpdateAccountDto
): Promise<UpdateAccountDto> {
let { bankName, accountName, accountNumber } = updateAccountDto;
const account = this.findOneOrFail(id);
const oldBankName = (await account).bankName;
const oldAccountName = (await account).accountNumber;
const oldAccountNumber = (await account).accountNumber;
if (bankName === null) {
bankName = oldBankName;
}
if (accountName === null) {
accountName = oldAccountName;
}
if (accountNumber === null) {
accountNumber = oldAccountNumber;
}
const query = this.createQueryBuilder('account');
await query
.update(Account)
.set({ bankName, accountName, accountNumber })
.where('account.id = :id', { id })
.execute();
return updateAccountDto;
}
account.controller.ts
#Put('/update/:id/')
updateAccount(#Param('id') id: string, #Body() uaDto: UADto) {
return this.accountService.updateAccount(id, uaDto);
}
account.service.ts
async updateAccount(id: string, updateAccountDto: UpdateAccountDto) {
return this.accountRepository.updateAccount(id, updateAccountDto);
}
account.dto
export class CreateAccountDto {
#IsNotEmpty()
accountName: string;
#IsNotEmpty()
accountNumber: string;
#IsNotEmpty()
bankName: string;
}
account.entity,ts
#Entity()
export class Account {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ nullable: true })
accountName: string;
#Column({ nullable: true })
accountNumber: string;
#Column({ nullable: true })
bankName: string;
}
I'm building a blog rest API based on Wordpress database schema!
I have linked wp_posts table with wp_term_taxonomy table with many to many relationships using typeORM framework
The problem is now when I'm creating a post with categories using cascade feature
it generates new categories even if it exists already I can't use exist categories with new posts!
So I need to just relation the existing categories ( taxonomies ) with new posts.
the code:
private createPost = async (request: express.Request, response: express.Response) => {
const data: WpPostsModel = request.body;
const entries: any[] = request.body.taxonomies;
let taxonomies = [];
for (let i = 0; i < entries.length; i++) {
const entry = entries[i];
let newTaxonomy = new WpTermTaxonomyModel();
newTaxonomy = {
taxonomy: entry.taxonomy,
description: '',
term: {
name: entry.term.name,
slug: entry.term.name.replace(/\s+/g, '-'),
term_group: 0,
// term_id: entry.term.term_id
}
}
taxonomies.push(newTaxonomy);
}
const newPost = await this.postRepository.create({
post_title: data.post_title,
post_content: data.post_content,
post_excerpt: data.post_excerpt,
post_type: 'post',
post_mime_type: '',
comment_status: 'closed',
ping_status: 'closed',
to_ping: '',
pinged: '',
comment_count: 0,
post_parent: 0,
post_status: 'publish',
post_content_filtered: '',
post_password: '',
post_name: ( data.post_title ) ? data.post_title.replace(/\s+/g, '-') : '',
post_date: new Date(),
post_date_gmt: new Date(),
post_modified: new Date(),
post_modified_gmt: new Date(),
taxonomies
});
await this.postRepository.save(newPost);
response.send(newPost);
}
wp_posts entity
#Entity({ name: 'wp_posts', synchronize: false })
export class WpPostsModel {
#PrimaryGeneratedColumn()
public ID?: number;
#Column()
public post_date?: string;
#Column()
public post_date_gmt?: string;
#Column()
public post_content?: string;
#Column()
public post_title?: string;
...etc
#ManyToMany(() => WpTermTaxonomyModel)
#JoinTable({
name: 'wp_term_relationships',
joinColumn: {
name: 'object_id',
referencedColumnName: 'ID'
},
inverseJoinColumn: {
name: 'term_taxonomy_id',
referencedColumnName: 'termTaxonomyId'
}
})
public categories?: WpTermTaxonomyModel[];
}
wp_term_taxonomy entity
#Entity({ name: 'wp_term_taxonomy', synchronize: false })
export class WpTermTaxonomyModel {
#PrimaryGeneratedColumn({ name: 'term_taxonomy_id' })
public termTaxonomyId?: number;
#OneToOne(() => WpTermsModel)
#JoinColumn({ name: 'term_id' })
public term?: WpTermsModel;
#Column()
public taxonomy?: string;
#Column()
public description?: string;
#Column()
public parent?: number;
}
wp_terms entity
#Entity({ name: 'wp_terms', synchronize: false })
export class WpTermsModel {
#PrimaryGeneratedColumn()
public term_id?: number;
#Column()
public name?: string;
#Column()
public slug?: string;
#Column()
public term_group?: number;
}
How to create new instance in TypeScript. Obviously I'm not matching the constructor but I can't see what's wrong.
export class User implements IUser {
public id: number;
public username: string;
public firstname: string;
public lastname: string;
public birthday: string;
public email: string;
public constructor(iUser: IUser)
{
this.id = iUser.id;
this.username = iUser.username;
this.firstname = iUser.firstname;
this.lastname = iUser.lastname;
this.birthday = iUser.birthday;
this.email = iUser.email;
}
}
interface IUser {
id?: number;
username: string;
firstname: string;
lastname: string;
birthday: string;
email: string;
}
And student class that extends user
export class Student extends User implements IStudent, IUser {
public indeks: string;
public studyProgram: StudyProgram;
public constructor(iUser: IUser, iStudent: IStudent)
{
super(iUser);
this.indeks = iStudent.indeks;
this.studyProgram = iStudent.studyProgram;
}
}
interface IStudent {
indeks: string;
studyProgram: StudyProgram;
}
So, when I try to create new instance of student I got this error
Supplied parameters do not match any signature of call target.
this.student = new Student ({
username: '',
firstname: '',
lastname: '',
birthday: '',
email: '',
indeks: '',
studyProgram: new StudyProgram({
name: '',
duration: 0,
courseType: ''
})
});
And here is StudyProgram class
export class StudyProgram implements StudyProgramInterface {
public id: number;
public name: string;
public duration: number;
public courseType: string;
public studentList: Array<Student>;
public constructor(studyProgramCfg: StudyProgramInterface) {
this.id = studyProgramCfg.id;
this.name = studyProgramCfg.name;
this.duration = studyProgramCfg.duration;
this.courseType = studyProgramCfg.courseType;
}
}
interface StudyProgramInterface {
id?: number;
name: string;
duration: number;
courseType: string;
}
The Student class constructor is expecting two objects (one implementing IStudent, and the other implementing IUser), you are passing only one. I think the constructor you are looking for is:
public constructor(student: IUser & IStudent) {
super(student);
this.indeks = student.indeks;
this.studyProgram = student.studyProgram;
}
You can find more about intersection types here: https://basarat.gitbooks.io/typescript/content/docs/types/type-system.html