Typeorm oneToOne relation - nestjs

Hi i have a relation between 'rooms' and 'room-servers'
RoomServers:
#Entity({ name: 'room-servers' })
export class RoomServer {
#PrimaryGeneratedColumn()
id: number;
#CreateDateColumn()
createdAt: Date;
#UpdateDateColumn()
updatedAt: Date;
}
Rooms:
#Entity({ name: 'rooms' })
export class Room {
#PrimaryGeneratedColumn()
id: number;
#Column({ default: '' })
name: string;
#Column({ nullable: true })
description: string;
#Column({ default: 'New' })
status: string;
#OneToOne(() => RoomServer, { nullable: false })
#JoinColumn()
roomServer: RoomServer;
}
When i type sql query
select * from "room-servers" rm left join rooms r on rm.id = r."roomServerId";
It returns results (3 servers that i have in database)
But when i try to use queryBuilder to see results:
const freeSocketServers = await this.roomServerRepository
.createQueryBuilder('room-servers')
.leftJoinAndSelect('room-servers.id', 'roomServerId')
.getMany();
console.log('freeSocketServer', freeSocketServers);
It returns nothing and i can't see console.log, it breaks on .leftJoinAndSelect

You set the relation in the room entity, To make it work you should go from room repository
const freeSocketServers = await this.roomRepository
.createQueryBuilder('room')
.leftJoinAndSelect('room.roomServer', 'room-server')
.getMany();
console.log('freeSocketServer', freeSocketServers);
Or you can make it Bi-directional see One-to-One

Related

I cannot update a join table with manyToMany property using nestjs and typeorm

I have set up a many to many relation between a user table and a spot table.
Here is the user entity:
#Entity('user')
export class UserEntity {
#PrimaryGeneratedColumn()
id: number;
#Column({ default: '' })
first_name: string;
#Column({ default: '' })
last_name: string;
#Column({ default: '' })
email: string;
#Column({ default: '' })
adress: string;
#Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
createdAt: Date;
#ManyToMany(() => SpotEntity, (spot) => spot.users)
#JoinTable({
name: 'spot_user',
joinColumn: {
name: 'user_id',
referencedColumnName: 'id',
},
inverseJoinColumn: {
name: 'spot_id',
referencedColumnName: 'id',
},
})
spots: Spot[];
}
And here is the spot entity:
#Entity('spot')
export class SpotEntity {
#PrimaryGeneratedColumn()
id: number;
#Column({ default: '' })
title: string;
#Column({ default: '' })
description: string;
#Column({ default: '' })
address: string;
#Column({ default: '' })
coordinates: string;
#Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
createdAt: Date;
#ManyToOne(() => TagEntity, (tag) => tag.spots)
tag: TagEntity;
#ManyToMany(() => UserEntity, (user) => user.spots)
users: User[];
}
This creates the join table as it should.
But now I am a bit confused as to how add a spot to a user.
To do so I added a service like so, which has access to both user and spot repository:
I a able to get the spot and the user, but the spot never saves into the user, and the join table is never updated.
async addSpotToUser(id?: number, spotId?: number): Promise<void> {
const mySpot = Object.values(spotId)[0];
const user = await this.userRepository.findOneBy({ id: Number(id) });
const spot = await this.spotRepository.findOneBy({ id: mySpot });
user.spots.push(spot);
this.userRepository.save(user);
}
}

How to Select Some Fields From Relations in Typeorm Relations

I need to Select Some fields from relations in Nest.js TypeOrm .
For Example My Entity is :
#Entity()
export class Chat {
#PrimaryGeneratedColumn()
public id: number;
#Column()
public orderId: number;
#Column({ default: ChatStatus.Active })
public status: ChatStatus;
#Column()
public userId: number;
#ManyToOne(() => User, (user) => user.chats, { nullable: true })
#JoinColumn({ name: 'userId' })
public user: User;
}
Any In My Service :
async findAll(dataSearch) {
return await this.chatRepository.find({
relations: ['user'],
});
}
I Want Just Select "name" , "avatar" from user relation but This select all Columns.
Thanks
#Column({ type: "timestamp", default: () => 'CURRENT_TIMESTAMP',
select: false
})
updated_at: Timestamp;
Example
#Column({ type: "timestamp", default: () => 'CURRENT_TIMESTAMP', select: false })

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;
}

How to do INNER JOIN in typeorm (postgresql)

I have this two entities:
#Entity()
export class Member {
#PrimaryColumn({ name: 'room_id' })
roomId: number;
#PrimaryColumn()
email: string;
#Column({ name: 'is_room_owner' })
isRoomOwner: boolean;
#Column('timestamp without time zone', { name: 'joined_at', nullable: true })
joinedAt: Date | null;
#CreateDateColumn({ name: 'created_at' })
createdAt: Date;
#ManyToOne(() => Room, room => room.members)
#JoinColumn({ name: 'room_id' })
room: Room;
}
#Entity()
export class Room {
#PrimaryGeneratedColumn({ name: 'room_id' })
roomId: number;
#Column()
name!: string;
#Column()
permanent!: boolean;
#Column()
active!: boolean;
#CreateDateColumn({ name: 'created_at' })
createdAt: Date;
#UpdateDateColumn({ name: 'updated_at' })
updatedAt: Date;
#OneToMany(() => Member, member => member.room, { cascade: true })
members: Member[];
}
I would like to get the rooms by the member's email and filter if they are active.
Basically in sql it would be something like this:
select "room".*, "member".* from room "room"
inner join member "member" on "member".roomId = "room".roomId
where "room".active = :active and "member".email = :email;
It should include the members.
I am getting used to typeorm so thanks a lot for any help!
The query can be constructed using query builder as follows -
async getRoomsByMember(active: boolean, email: string): Promise<any[]> {
return await getRepository(Room)
.createQueryBuilder('room')
.innerJoinAndSelect('room.member', 'member')
.where("room.active = :active", {active: active})
.andWhere("member.email = :email", { email: email })
.getMany();
}

How to Get data in mutiple #ManyToMany in Nest.js

I have a ManyToMany relation between two entities and I don't know how can I Get data from the join table "device_users_user"
#Entity()
export class Device{
#PrimaryColumn()
Name:string;
#Column({ nullable: true})
Port:number;
#Column({ nullable: true})
IPadress:string;
#Column({ nullable: true})
Location:string;
#ManyToMany(type => User)
#JoinTable()
users: User[];
}
#Entity()
export class User{
#PrimaryColumn()
Id:number;
#Column({ nullable: true})
Departement:string;
#Column({ nullable: true})
FirstName:string;
#Column({ nullable: true})
LastName:string;
#Column({ nullable: true})
CardNumber:string;
#Column({ nullable: true})
MobilePhone:string;
}
You cannot query the join table directly, using the TypeORM API's (unless you try to do a raw query, but I assume this is not what you want to achieve... And I don't recommend it, as table names might be changed...).
However, as you declared the relation using #ManyToMany, you can load the users of your devices with a Query Builder, for instance:
const devicesWithUsers = await deviceRepository.createQueryBuilder('device')
.leftJoin('device.users', 'user')
.where(/* whatever you need */)
.getMany();
The documentation of TypeORM gives more examples, e.g.:
const user = await createQueryBuilder("user")
.leftJoinAndSelect("user.photos", "photo")
.where("user.name = :name", { name: "Timber" })
.getOne();
which could gives, as a result:
{
id: 1,
name: "Timber",
photos: [{
id: 1,
url: "me-with-chakram.jpg"
}, {
id: 2,
url: "me-with-trees.jpg"
}]
}

Resources