Reputation: 497
So. I've setup pretty much everything for the creation of my Item. When i try to run it in Postman i get the error named in the title. The concerning column is cancellation
from the table "Item". In postman, I clearly define it as true (which is not null). And also interesting is the fact that it doesn't complain about the delivery
column which is the exact same type as cancellation
Item entity
import { Category } from './category.entity';
import { Rent } from './rent.entity';
import { User } from './user.entity';
import {
BaseEntity,
Column,
Entity,
JoinTable,
ManyToMany,
ManyToOne,
OneToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
@Entity('item')
export class Item {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
description: string;
@Column()
price: number;
@Column()
delivery: boolean;
@Column()
cancellation: boolean;
@Column({ nullable: true })
rating: number;
@Column()
imageUrl: string;
@ManyToOne(() => User, (user) => user.items, {
onDelete: 'CASCADE',
})
user: User;
@OneToOne(() => Rent, (rent) => rent.item)
rent: Rent;
@ManyToMany(() => Category, (category) => category.items)
@JoinTable()
categories: Category[];
}
Create item DTO
import {
IsBoolean,
IsNotEmpty,
IsNumber,
IsOptional,
IsString,
} from 'class-validator';
export class CreateItemDto {
@IsString()
@IsNotEmpty()
name: string;
@IsString()
@IsNotEmpty()
description: string;
@IsNumber()
@IsNotEmpty()
price: number;
@IsBoolean()
@IsNotEmpty()
delivery: boolean;
@IsBoolean()
@IsNotEmpty()
cancellation: boolean;
@IsOptional()
rating: number;
@IsNotEmpty()
userId: number;
@IsOptional()
imageUrl: string;
}
User entity
import { Item } from './item.entity';
import { Rent } from './rent.entity';
import { Review } from './review.entity';
import {
BaseEntity,
Column,
Entity,
OneToMany,
PrimaryGeneratedColumn,
} from 'typeorm';
@Entity('user')
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column('varchar', { length: 50 })
name: string;
@Column('varchar', { length: 50 })
surname: string;
@Column('varchar', { length: 50 })
street: string;
@Column('varchar', { length: 50 })
city: string;
@Column('varchar', { length: 5 })
zip: string;
@Column({ type: 'int', nullable: true })
rating: number;
@Column('varchar', { length: 10 })
phone: string;
@Column('date')
date: Date;
@Column({ type: 'varchar', length: 50, nullable: false, unique: true })
email: string;
@Column({ type: 'varchar', length: 75, nullable: false })
password: string;
@OneToMany(() => Review, (review) => review.user)
reviews: Review[];
@OneToMany(() => Rent, (rent) => rent.user)
rents: Rent[];
@OneToMany(() => Item, (item) => item.user)
items: Item[];
}
Items service
import { CreateItemDto } from './dto/createItem.dto';
import { ItemsRepository } from './items.repository';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Item } from 'src/entities/item.entity';
import { User } from 'src/entities/user.entity';
@Injectable()
export class ItemsService {
constructor(
@InjectRepository(ItemsRepository)
private itemsRepository: ItemsRepository,
) {}
async getItemById(id: number) {
return await this.itemsRepository.findOne(id);
}
async createItem(createItemDto: CreateItemDto, user: User): Promise<Item> {
const newItem = await this.itemsRepository.save({
name: createItemDto.name,
description: createItemDto.description,
price: createItemDto.price,
delivery: createItemDto.delivery,
rating: createItemDto.rating,
imageUrl: createItemDto.imageUrl,
});
user.items = [...user.items, newItem];
await user.save();
return newItem;
}
}
Items controller
import { AuthService } from './../auth/auth.service';
import { CreateItemDto } from './dto/createItem.dto';
import { ItemsService } from './items.service';
import { Body, Controller, Post } from '@nestjs/common';
import { Item } from 'src/entities/item.entity';
@Controller('items')
export class ItemsController {
constructor(
private itemsService: ItemsService,
private authService: AuthService,
) {}
@Post('/createitem')
async createItem(@Body() createItemDto: CreateItemDto): Promise<Item> {
const user = await this.authService.getUserById(createItemDto.userId);
return this.itemsService.createItem(createItemDto, user);
}
}
Auth service
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { SignUpDto } from './dto/signup.dto';
import { SignInDto } from './dto/signin.dto';
import { UsersRepository } from './users.repository';
import * as bcrypt from 'bcrypt';
import { JwtService } from '@nestjs/jwt';
import { JwtPayload } from './jwt-payload.interface';
import { User } from 'src/entities/user.entity';
@Injectable()
export class AuthService {
constructor(
@InjectRepository(UsersRepository)
private usersRepository: UsersRepository,
private jwtService: JwtService,
) {}
async signUp(signUpDto: SignUpDto): Promise<void> {
return this.usersRepository.createUser(signUpDto);
}
async signIn(signInDto: SignInDto): Promise<{ accessToken: string }> {
const { email, password } = signInDto;
const user = await this.usersRepository.findOne({ email });
if (user && (await bcrypt.compare(password, user.password))) {
const payload: JwtPayload = { email };
const accessToken: string = await this.jwtService.sign(payload);
return { accessToken };
} else {
throw new UnauthorizedException('Check your login credentials');
}
}
async getUserById(id: number): Promise<User> {
return await this.usersRepository.findOne(id, { relations: ['items'] });
}
}
Items module
import { AuthModule } from './../auth/auth.module';
import { AuthService } from './../auth/auth.service';
import { ItemsRepository } from './items.repository';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Module } from '@nestjs/common';
import { ItemsController } from './items.controller';
import { ItemsService } from './items.service';
@Module({
imports: [TypeOrmModule.forFeature([ItemsRepository]), AuthModule],
controllers: [ItemsController],
providers: [ItemsService],
})
export class ItemsModule {}
Upvotes: 2
Views: 11089
Reputation: 592
If you have added a one-to-many relationship between entities, in your Nestjs project. Or some other relationship. You can delete all the rows of the each tables in question to fix the error.
For example ins a one-to-many relationship.
User 1-->* Task
user.entity.ts
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({ unique: true})
username: string;
@Column()
password: string;
@Column({ unique: true})
email: string;
@OneToMany(() => Task, (task) => task.user)
@JoinColumn({ name: 'id', referencedColumnName: 'userId'})
tasks: Task[];
}
task.entity.ts
@Entity()
export class Task {
@PrimaryGeneratedColumn()
id: number;
// @Column({ unique: true})
@Column('text')
description: string;
@Column({ type: 'enum', enum: TaskStatus, default: TaskStatus.OPEN})
status: TaskStatus;
@Column({ name: 'created_at', type: 'timestamp', default: () => 'CURRENT_TIMESTAMP'})
date: Date;
@DeleteDateColumn({ name: 'deleted_at', type: 'timestamp', nullable: true })
deletedAt: Date;
@Column({ name: 'user_id'})
userId: number;
@ManyToOne(() => User, (user) => user.tasks)
@JoinColumn({ name: 'userId'})
user: User;
}
Delete all rows of the two tables.
delete from user;
delete from task ;
Upvotes: 0
Reputation: 2987
You forgot to add the cancellation
property:
const newItem = await this.itemsRepository.save({
name: createItemDto.name,
description: createItemDto.description,
price: createItemDto.price,
delivery: createItemDto.delivery,
rating: createItemDto.rating,
imageUrl: createItemDto.imageUrl,
cancellation: createItemDto.cancellation, // this one
});
Upvotes: 1