typeorm save in joined cloumn - node.js

in my project i have two entity, naturalist(user) and comment entity
i create relation between them, how to save reciever_id (joined cloumn) in comment entity
this is my comment entity
#Entity()
export class Comments extends BaseEntity {
#PrimaryGeneratedColumn()
id: string
#ManyToOne(
type => Naturalist,
naturalist => naturalist.comments
)
#JoinColumn({
name: 'naturalist_id',
})
naturalist: Naturalist
#Column({ nullable: true, default: '' })
text?: string
#Column({ nullable: true, default: '' })
sender_id?: string
}
naturalist(my user) entity
#Entity()
export class Naturalist extends BaseEntity {
#PrimaryGeneratedColumn()
id: number
#Column()
user_id: string
#OneToMany(
type => Comments,
comment => comment.naturalist
)
comments: Comments[]
}
DTO contains
{
receiver_id: '2cc2f359-821c-4940-99ae-7386576d861b',
text: 'string',
id: 'e0464049-d1d9-474a-af5b-815805aa1c4b'
}
i want to save receiver_id to my comment entity

if I understand correctly your needs,
I think you need an insert method to do this:
await entityManager.insert(Comments, { naturalist: { id: '2cc2f359-821c-4940-99ae-7386576d861b' } as Naturalist });

Related

It is possible to do that OneToMany and ManyToMany between two entities or needs to be ManyToMany?

So a company can have multiple locations, that means OneToMany.
A Country can have multiple companies.
First I tried with ManyToOne in Country but I can have only 1 companyid per location.
How can I do that thing with the third table?
company.entity.ts
#Entity('company')
export class Company extends BaseEntity {
#PrimaryGeneratedColumn()
id: number
#IsString()
#Column({ type: 'varchar', nullable: true })
mission_statement: string
#IsDateString()
#Column({ type: 'date', nullable: true })
founded_in: Date
#OneToMany(() => Country, (country) => country.countryId, { eager: true })
locations: Country[]
}
country.entity.ts
#Entity('countries')
export class Country extends BaseEntity {
#PrimaryGeneratedColumn('uuid')
id: string
#IsNotEmpty()
#Column({ unique: true })
name: string
#ManyToMany(() => Company, (company) => company.locations, { nullable: true })
#JoinColumn({ name: 'company_id' })
countryId: Company[]
}
I know I should create a third entity for storing the relationship between them but I tried 4 times and for nothing. Do you think you can help me?

How to save data from a one-to-one relationship in a so-call? TYPEORM and NESTJS

I have two entities to create in the table, one for the user and the other to store the token, and when creating a user I need both to be filled in, but I don't know how to do that via the ORM of TYPEORM, how would you do a create?
UserEntity
#Entity('Users')
export class UserEntity {
#ObjectIdColumn()
_id: ObjectId;
#Column({ type: 'string', length: 24 })
name: string;
#Column({ type: 'string', length: 55 })
password: string;
#Column({ type: 'string', length: 24 })
email: string;
#Column({ type: 'number', length: 24 })
celphone: number;
#OneToOne(() => TokenEntity, (TokenEntity) => TokenEntity.user, {
cascade: true,
})
#JoinColumn()
token: TokenEntity;
#CreateDateColumn()
created_at: Date;
#UpdateDateColumn()
updated_at: Date;
}
TokenEntity
#Entity('UserTokens')
export class TokenEntity {
#ObjectIdColumn()
_id: ObjectId;
#OneToOne(() => UserEntity, (user) => user.token)
user: UserEntity;
#Column({ type: 'string', length: '100' })
accessToken: string;
#Column({ type: 'number' })
expereIn: number;
}
UPDATED ---
code repo
export class CreateUserRepo implements ICreateUserContract {
constructor(private menagerRepo: EntityManager) {}
public async create({
user,
token,
}: ICreateUserContract.Input): Promise<void> {
const createUserByToken = new TokenEntity();
createUserByToken.accessToken = token.accessToken;
createUserByToken.expereIn = token.expireIn;
const createUser = new UserEntity();
createUser.name = user.name;
createUser.password = user.password;
createUser.celphone = user.celphone;
createUser.email = user.email;
createUser.token = createUserByToken;
await this.menagerRepo.save(createUser);
}
}
----- Updated
it is saving in both as expected, but in the User document it is saving a Token column, with token info, but I don't want that, I want a connection only, not to save the information in the same document...
As far as I understand, what you want is a bi-directional relation, which is described by typeorm. You attempted that with the inverse sides (UserEntity) => UserEntity.id and (TokenEntity) => TokenEntity.id. However, you want to access UserEntity and TokenEntity respectively, not their id. Change the accessors to (TokenEntity) => TokenEntity.user and (UserEntity) => UserEntity.tokenId, as they are declared in their classes.

Typeorm migration with bi-directional manytomany resulting in TypeError: Class exends value undefined is not a constructor or null

I'm working on a nestjs project with TypeORM. I'm setting up a bidirectional ManyToMany relationship between two entities: Notes and Gcalevents. Every Note could be linked to multiple Gcalevents, and every Gcalevent could be linked to many Notes.
Snippets from my entity definitions look like this:
base.entity.ts:
export class BaseEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ type: 'boolean', default: true })
isActive: boolean;
... // some more fields
}
note.entity.ts:
import { Gcalevent } from './gcalevent.entity';
import { BaseEntity } from './base.entity';
#Entity({ name: 'note' })
export class Note extends BaseEntity {
#Column({ type: 'varchar', length: 300 })
title: string;
...
#ManyToMany(() => Gcalevent, (gcalevent) => gcalevent.notes)
#JoinTable()
gcalevents: Gcalevent[]
}
gcalevent.entity.ts:
import { Note } from "./note.entity";
#Entity({ name: 'gcalevent' })
export class Gcalevent {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({
type: 'varchar',
nullable: false,
})
eventId: string;
...
#ManyToMany(() => Note, (note) => note.gcalevents)
notes: Note[]
}
I believe I'm declaring the ManyToMany relationships correctly, but when I try to generate the TypeORM migration, I get the error TypeError: Class extends value undefined is not a constructor or null, which points to both the note.entity and gcalevent.entity files
I'm guessing this has something to do with the gcalevent.entity and note.entity files importing each other, combined with the note.entity file importing BaseEntity, but not sure how to fix it!
I had the same problem, I've found here
this "workaround" for the issue.
Try using "strings" instead of "types" in the #ManyToMany decorator:
note.entity.ts:
import { Gcalevent } from './gcalevent.entity';
import { BaseEntity } from './base.entity';
#Entity({ name: 'note' })
export class Note extends BaseEntity {
#Column({ type: 'varchar', length: 300 })
title: string;
...
#ManyToMany("Gcalevent","notes")
#JoinTable()
gcalevents: Gcalevent[]
}
gcalevent.entity.ts:
import { Note } from "./note.entity";
#Entity({ name: 'gcalevent' })
export class Gcalevent {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({
type: 'varchar',
nullable: false,
})
eventId: string;
...
#ManyToMany("Note","gcalevents")
notes: Note[]
}

Usage of ManyToOne relation returns null in TypeGraphQL

For learning, I made a project testing out TypeGraphql, together with TypeORM. I have a User and Book entity, where I want to have a created_by field on the Book entity.
#ObjectType()
#Entity()
export class Book extends BaseEntity {
#Field(() => ID)
#PrimaryGeneratedColumn()
readonly id: number;
#Field({ nullable: true })
#Column({ nullable: true })
name: string;
#Field(() => User)
#ManyToOne(() => User)
#JoinColumn({ name: 'created_by' })
created_by: User;
// #RelationId((orthodontist: Orthodontist) => orthodontist.created_by)
// createdById: number;
}
#ObjectType()
#Entity()
export class User extends BaseEntity {
#Field(() => ID)
#PrimaryGeneratedColumn()
id: number;
#Field({ nullable: true })
#Column({ nullable: true })
first_name?: string;
#Field({ nullable: true })
#Column({ nullable: true })
last_name?: string;
#Field()
#Column({ unique: true })
email: string;
#Column()
password: string;
#Field(() => [Book!])
#OneToMany(() => Book, book => book.created_by)
created_books: Book[];
}
For my resolver, it simply looks like this, which I am properly loading as the docs say.
#Resolver(Book)
export class OrthodontistResolver {
#Query(() => [Book])
books(): Promise<Book[]> {
return Book.find();
}
}
When I go into my GraphQL playground, and query something like this:
{
books {
name,
id,
}
}
It all works and returns the right data. However, when I try to use the created_by field like this:
{
orthodontists {
name,
id,
created_by {
id
}
}
}
It gives me the following error:
Cannot return null for non-nullable field Book.created_by.
I made sure the relation exists in the database, and set up correctly with it's FK's. Where does this come from though? How can I fix this? I did try using the #RelationId decorator, as seen in the first code example. It unfortunately didn't work.
EDIT:
There is only one book in the database, where the created_by field is not null.
Change your books resolver to return the relationship created_by when using find operation:
#Resolver(Book)
export class OrthodontistResolver {
#Query(() => [Book])
books(): Promise<Book[]> {
return Book.find({
relations: ["created_by"],
});
}
}

Find - relations xxx not found

I am trying to return and entity including its relation but I am getting an error saying relation xxx not found. I am using the repository pattern.
#Entity({ name: 'person' })
export class PersonEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ type: 'number' })
statusId: number;
#ManyToOne(() => StatusEntity, status => status.id)
status: StatusEntity;
}
#Entity({ name: 'statuses' })
export class StatusEntity {
#PrimaryGeneratedColumn('increment')
id: number;
#Column({ type: 'varchar', length: 256 })
name: string;
}
I am using postgres and I have a foreign key declared:
"public"."person" ADD CONSTRAINT "FK_person_statusid" FOREIGN KEY ("statusId") REFERENCES "public"."statuses"("id")
In my service:
public async getAll(): Promise<PersonEntity[]> {
return await this.personRepository.find({ relations: ['statuses'] });
}
#Entity({ name: 'person' })
export class PersonEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ type: 'number' })
statusId: number;
#ManyToOne(() => StatusEntity)
#JoinTable()
status: StatusEntity;
}
#Entity({ name: 'status' })
export class StatusEntity {
#PrimaryGeneratedColumn()
id: number;
#Column({ type: 'varchar', length: 256 })
name: string;
}
Note that I have changed StatusEntity name from statuses to status.
Could you delete the foreign key you created manually, and then update your entity like below and try?
#Entity({ name: 'person' })
export class PersonEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ type: 'number' })
statusId: number;
#ManyToOne(() => StatusEntity)
#JoinColumn({ name: 'statusId })
status: StatusEntity;
}

Resources