Get entities within 100km with postgresql and typeorm ordered - postgresql

I get this error
Cannot read property 'databaseName' of undefined
https://github.com/typeorm/typeorm/issues/4270
I follow github issue but it not help, the query works correctly If I delete addOrderBy method
but I need the results ordered by the distance so there is a way to make this work ?
Entity
#Entity('restaurant')
export class RestaurantEntity extends AbstractEntity {
#Column()
name: string;
#Column()
description: string;
#OneToMany(() => MenuEntity, (menu) => menu.restaurant, {
onDelete: 'CASCADE',
cascade: true,
})
menus: MenuEntity[];
#Column()
type: string;
#Column()
location: string;
#Column('geometry', {
name: 'geo',
nullable: true,
spatialFeatureType: 'Point',
})
geoLocation: object;
#Column({
nullable: true,
})
likes: number;
#OneToMany(
() => RestaurantImageEntity,
(restaurantImage) => restaurantImage.restaurant,
{
onDelete: 'CASCADE',
cascade: true,
},
)
restaurantImages: RestaurantImageEntity[];
#Column({
nullable: true,
})
views: number;
#Column({
nullable: true,
})
totalFavorites: number;
#Column({
nullable: true,
})
telephone: string;
#Column({
nullable: true,
})
web: string;
#Column({
nullable: true,
})
email: string;
#ManyToOne(() => UserEntity, (user) => user.restaurants, {
onDelete: 'CASCADE',
})
creator: UserEntity;
}
Query
const query.geoLocation = [x,y];
restaurants = await this.restaurantRepository
.createQueryBuilder('restaurant')
.leftJoinAndSelect('restaurant.restaurantImages', 'restaurantImages')
.where(ST_DWithin(restaurant.geoLocation, ST_MakePoint(${query.geoLocation[0]},${query.geoLocation[1]})::geography, 100000))
.orderBy(sort ? sort : { 'restaurant.id': 'DESC' })
.addOrderBy(`restaurant.geoLocation <-> ST_MakePoint(${query.geoLocation[0]},${query.geoLocation[1]})::geography`)
.skip((page - 1) * perPage)
.take(perPage)
.getMany();

Related

Cannot read properties of undefined reading 'getEntityValue' typeorm

I am creating a nestjs project with typeorm and postgresql. Here I am creating a user entity.
My entity will be like
{
email: string,
name: string,
avatar: {
public_key: string;
url: string;
}
}
In avatar column I need to add a object with public_key and url.
I create two entity like this-
#Entity()
class Avatar {
#Column({ type: "text", nullable: true })
public_key: string;
#Column({ type: "text", nullable: true })
url: string;
}
#Entity()
#Tree("closure-table")
export class User {
#PrimaryGeneratedColumn()
id: number;
#Column({ type: "text", nullable: false })
userName: string;
#Column({ type: "text", nullable: false })
email: string;
#Column({ type: "text", nullable: false })
firstName: string;
#Column({ type: "text", nullable: false })
lastName: string;
#Column({ type: "text", nullable: false, select: false })
password: string;
#Column({ type: "text", nullable: true })
socket_id: string;
#Column({ type: "text", nullable: true, select: false })
otp: string;
#TreeChildren()
avatar: Avatar;
#Column({ type: "boolean", default: false, nullable: false })
is_verify: boolean;
#CreateDateColumn()
created_at: Date;
#UpdateDateColumn()
updated_at: Date;
//Before Insert Injection
#BeforeInsert()
createUserName() {
this.userName = uniqid.time()
}
}
Here I use closure-table to do nested avatar entity
Here I write
#TreeChildren()
avatar: Avatar;
For nesting Avatar Entity
Then in my controller I try to create my first data-
const result = await this.userRepository.create({
...userInput,
otp: secret.base32,
password: passwordHash,
});
await this.userRepository.save(result)
Note: avatar field is not required. Avatar field will be add when user update their profile. Here I only create first user data.
But I am getting this error-
Cannot read properties of undefined (reading 'getEntityValue')
Additionally, here is my userInput
#InputType()
export class UserInput {
#Field(() => String, { nullable: false })
#IsString()
#IsEmail()
#IsNotEmpty()
email: string;
#Field(() => String, { nullable: false })
#IsString()
#IsNotEmpty()
firstName: string;
#Field(() => String, { nullable: false })
#IsString()
#IsNotEmpty()
lastName: string;
#Field(() => String, { nullable: false })
#IsString()
#MinLength(8)
#MaxLength(20)
#IsNotEmpty()
#Matches(/^.*(?=.{4,10})(?=.*\d)(?=.*[a-zA-Z]).*$/, { message: "password too weak" })
password: string
}
Please help me. I need this is very much. Over 10 days, I can't solve this. Please help me.

Problem connecting tables in Sequelize-Typescript NestJS

There are 3 tables: users, posts, likes, (roles - but it works fine). One user has multiple posts and multiples likes. One post has multiple likes. As I understand, connections are
User #HasMany(() => Post) and #HasMany(() => Like)
Post #HasMany(() => Like)
Problem: In my user.service.ts when I run this function
const user = await this.userRepository.findOne({ where: { email }, include: { all: true } })
return user
it gets Error:
likes.userId column does not exist
Code:
Users ->
#Table({ tableName: 'users' })
export class User extends Model<User> {
#Column({ type: DataType.INTEGER, unique: true, autoIncrement: true, primaryKey: true })
id: number;
#Column({ type: DataType.STRING, unique: true, allowNull: false })
email: string;
#Column({ type: DataType.STRING, allowNull: false })
password: string;
#BelongsToMany(() => Role, () => UserRoles)
roles: Role[]
#HasMany(() => Post)
posts: Post[]
#HasMany(() => Like)
likes: Like[]
Posts ->
#Table({ tableName: 'posts' })
export class Post extends Model<Post> {
#Column({ type: DataType.INTEGER, unique: true, autoIncrement: true, primaryKey: true })
id: number;
#Column({ type: DataType.STRING, allowNull: false })
title: string;
#Column({ type: DataType.STRING, allowNull: false })
content: string;
#ForeignKey(() => User)
#Column({ type: DataType.INTEGER })
userId: number;
#BelongsTo(() => User)
author: User;
#HasMany(() => Like)
likes: Like[]
Likes ->
#Table({ tableName: 'likes' })
export class Like extends Model<Like> {
#Column({ type: DataType.INTEGER, unique: true, autoIncrement: true, primaryKey: true })
id: number;
#ForeignKey(() => Post)
#Column({ type: DataType.INTEGER })
postId: number;
#BelongsTo(() => Post)
post: Post
#ForeignKey(() => User)
#Column({ type: DataType.INTEGER })
userId: number;
#BelongsTo(() => User)
author: User
}
Repo: https://github.com/keeeparis/Todo-Nest-React-Postgre
What am I missing?
That was my mistake. When you editing columns, you manually need to delete some related tables in order to see the changes. Yes, simple as that.

TypeORM one-to-many / many-to-one array empty and foreign key is null

I must be doing something wrong and I can not solve this issue.
I have two entities in my API
Collection
Asset
Each asset belongs to one collection
A Collection holds many Assets
These are my entity classes
import {
Entity,
Column,
PrimaryGeneratedColumn,
JoinColumn,
OneToOne,
CreateDateColumn,
UpdateDateColumn,
OneToMany,
} from 'typeorm';
import { CollectionStats } from '../../../database/entities/opensea/CollectionStats';
import { Asset } from './Asset';
import { AssetContract } from './interfaces/AssetContract';
import { PaymentToken } from './interfaces/PaymentToken';
#Entity()
export class Collection {
#PrimaryGeneratedColumn()
id: number;
#Column()
name: string;
#Column({ nullable: true })
external_link: string;
#Column({ nullable: true })
description: string;
#Column({ unique: true, nullable: false })
slug: string;
#Column({ nullable: true })
image_url: string;
#Column({ nullable: true })
banner_image_url: string;
#Column()
dev_seller_fee_basis_points: string;
#Column()
safelist_request_status: string;
#Column({ nullable: true })
payout_address: string;
#Column('jsonb')
primary_asset_contracts: AssetContract[];
#Column('simple-json')
traits: object;
#Column('jsonb', { nullable: true })
payment_tokens: PaymentToken[];
#Column('varchar', { array: true, nullable: true })
editors: string[];
#OneToOne(() => CollectionStats, { eager: true, cascade: true })
#JoinColumn()
stats: CollectionStats;
#OneToMany(() => Asset, (asset) => asset.collection, { cascade:true, eager: true })
assets: Asset[];
#Column({ type: 'timestamptz' })
created_date: Date;
#CreateDateColumn()
created_at: Date;
#UpdateDateColumn()
updated_at: Date;
}
import {
Column,
Entity,
JoinColumn,
ManyToOne,
OneToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
import { ColumnNumericOptions } from 'typeorm/decorator/options/ColumnNumericOptions';
import { Collection } from './Collection';
import { CollectionStats } from './CollectionStats';
import { AssetContract } from './interfaces/AssetContract';
import { Owner } from './interfaces/Owner';
import { PaymentToken } from './interfaces/PaymentToken';
import { Trait } from './interfaces/Trait';
#Entity()
export class Asset {
#PrimaryGeneratedColumn()
id: number;
#Column({ nullable: false })
token_id: string;
#Column({ default: 0 })
num_sales: number;
#Column({ nullable: true })
background_color: string;
#Column({ nullable: true })
image_url: string;
#Column({ nullable: true })
image_preview_url: string;
#Column({ nullable: true })
image_thumbnail_url: string;
#Column({ nullable: true })
image_original_url: string;
#Column({ nullable: true })
animation_original_url: string;
#Column({ nullable: true })
external_link: string;
#Column({ nullable: true })
description: string;
#Column('simple-json')
asset_contract: AssetContract;
#Column({ nullable: true })
permalink: string;
#ManyToOne(() => Collection, (collection) => collection.assets)
collection: Collection;
#Column({ nullable: true })
decimals: number;
#Column({ nullable: true })
token_metadata: string;
#Column('simple-json')
owner: Owner;
#Column('simple-json', { array: false, nullable: true })
sell_orders: Object;
#Column('simple-json', { nullable: true })
traits: Trait[];
#Column('simple-json', { nullable: true })
last_sale: Object;
#Column('simple-json', { nullable: true })
top_bid: Object;
#Column('timestamptz', { nullable: true })
listing_date: Date;
#Column({ default: false })
is_presale: boolean;
#Column('simple-json', { nullable: true })
transfer_fee_payment_token: PaymentToken;
#Column({ nullable: true })
transfer_fee: number;
}
This is the the function where everything should get linked together
const collection = await getCustomRepository(CollectionRepository).create(
collectionResponse.collection as Object,
);
const assets = await this.fetchAssets(collection); //Returns an Array of type Asset
const stats = await getCustomRepository(CollectionStatsRepository).create(
statsResponse.stats as Object,
);
collection.stats = stats; //this works properly
collection.assets = assets; //this is not working
return await getCustomRepository(CollectionRepository).save(collection);
The response from getCustomRepo(CollectionRepo).save(collection) actually shows all the collection data including an array holding all the assets as I want it to be. However, when I open the postgres client, the collection table has no "assets" column and the assets table's collectionId column only contains "null"
the collection.find() also is only returning an empty assets[]
What am I doing wrong here?

Updating PSQL Tables with Relationships between Entities Using NestJS, TypeORM, GraphQL

I've been struggling for a week now on creating new tables and updating the TypeORM entities on the backend. We're using NestJS, GraphQL, and TypeORM with a PSQL database. We have a production server/database setup with clients' information saved already. I'm trying to add a new table to the database using a code-first approach to generate schema. On the master branch of the repo, I start it up in my local environment, and connect to a clean database. Once I create accounts, and save information to the tables, I then switch to a new branch that contains the code for implementing the new table, including the module, service, entity, and resolver. If I try to run this branch and connect to the same database I was using on master, it fails to compile, fails to generate a schema.gql file, and stops at "GraphQLModule dependencies initialized." This new table that I created has a ManyToOne relationship with the Teams table, that already has values contained in it. For some reason, I think TypeORM is failing to update the database properly, and I don't know why. If I create a new database, and connect to the new database on the branch with the new table code, it works just fine, and no errors are thrown. Problem is if I connect to the original database, no error is thrown, but the code fails to compile, and I don't know how to debug it.
Has anyone had any issue adding new tables to their PSQL database using TypeORM, Nest, and GraphQL?
Here are some code snippets showing what I mean:
Entity for Waiver Table (exists on the old database already)
#Entity({ name: 'waivers' })
#ObjectType()
export class WaiverEntity extends BaseEntity {
#Field(() => ID)
#PrimaryGeneratedColumn('uuid')
id: string;
#Field(() => AccountEntity)
#ManyToOne(
() => AccountEntity,
creator => creator.waivers,
{ onDelete: 'SET NULL' },
)
#JoinColumn()
creator: Promise<AccountEntity>;
#Field(() => TeamEntity)
#ManyToOne(
() => TeamEntity,
team => team.waivers,
{ onDelete: 'CASCADE' },
)
#JoinColumn()
team: Promise<TeamEntity>;
#Field(() => ID)
#Column({ nullable: true })
creatorId: string;
#Field(() => ID)
#Index()
#Column({ nullable: true })
teamId: string;
#Field()
#Column('json')
organizer: Organizer;
#Field()
#Column('json')
event: Event;
#Field()
#Column('json', { nullable: true })
eventDate: EventDate;
#Field({ nullable: true })
#Column()
includeEmergencyContact: boolean;
#Field({ nullable: true })
#Column({ nullable: true })
customerLabel: string;
#Field(() => CustomEntity, { nullable: true, defaultValue: [] })
#Column('jsonb', { nullable: true })
intensity: CustomEntity;
#Field(() => [CustomEntity], { nullable: true, defaultValue: [] })
#Column('jsonb', { nullable: true })
activities: CustomEntity[];
#Field({ defaultValue: waiverStatus.DRAFT, nullable: false })
#Column({ default: waiverStatus.DRAFT, nullable: false })
status: string;
#Field({ nullable: true })
#Column({ type: 'varchar', nullable: true })
title: string;
#Field({ nullable: true })
#Column({ nullable: true })
body: string;
#Field({ nullable: true })
#Column({ nullable: true, default: signatureDefaultContent })
signatureContent: string;
#Field(() => [String], { nullable: true })
#Column('simple-array', { nullable: true })
ageGroup: string[];
#Field(() => [AdditionalFields], { nullable: false, defaultValue: [] })
#Column('jsonb', { nullable: true })
additionalFields: AdditionalFields[];
#Field({ nullable: false })
#Column({ nullable: false })
step: number;
#Exclude()
#Field({ nullable: true })
#Column({ nullable: true, unique: true })
pdfURL: string;
#BeforeInsert()
cleanUpBeforeUpdate(): void {
// add Prefix on retrieval
if (this.organizer && this.organizer.photoURL) {
try {
const photoUrls = this.organizer.photoURL.split(
`${AWS_BUCKETS.ORGANIZATION_BUCKET_IMAGE}/`,
);
this.organizer.photoURL =
photoUrls.length > 1 ? photoUrls[1] : this.organizer.photoURL;
} catch (e) {}
}
}
#AfterLoad()
updateURLs(): void {
// add Prefix on retrieval
this.pdfURL = this.pdfURL
? `${getBucketPrefix(
AWS_BUCKETS_TYPES.WAIVER_BUCKET_FILES,
'https://',
)}/${this.pdfURL}`
: null;
if (this.organizer) {
this.organizer.photoURL = this.organizer.photoURL
? `${getBucketPrefix(
AWS_BUCKETS_TYPES.ORGANIZATION_BUCKET_IMAGE,
'https://',
)}/${this.organizer.photoURL}`
: null;
}
}
#Field({ nullable: true })
#Column({ type: 'timestamp', nullable: true })
#IsDate()
publishDate: Date;
#Field({ nullable: true })
#Column({ nullable: true, unique: true })
slug: string;
#Field(() => [DownloadEntity], { nullable: true })
#OneToMany(
() => DownloadEntity,
downloadEntity => downloadEntity.waiver,
)
#JoinColumn()
waiverDownloads: Promise<DownloadEntity[]>;
#Field({ defaultValue: 0 })
downloadCount: number;
#Field(() => [WaiverMembersEntity])
#OneToMany(
() => WaiverMembersEntity,
waiverMember => waiverMember.account,
)
accountConnection: Promise<WaiverMembersEntity[]>;
#Field(() => [WaiverConsentsEntity])
#OneToMany(
() => WaiverConsentsEntity,
waiverMember => waiverMember.waiver,
)
consent: Promise<WaiverConsentsEntity[]>;
#Field(() => [AccountEntity])
waiverMember: AccountEntity[];
#Field(() => [ParticipantsEntity])
#OneToMany(
() => ParticipantsEntity,
participant => participant.waiver,
)
participants: ParticipantsEntity[];
#Field({ defaultValue: 0 })
totalResponses: number;
#Field()
eventName: string;
#Field({ nullable: true })
#Column({ type: 'varchar', nullable: true })
smsContent: string;
#Field({ nullable: true })
#Column({ nullable: true })
smsCode: string;
#Field()
#Column({ type: 'timestamp', default: () => timeStamp })
#IsDate()
createdAt: Date;
#Field()
#Column({
type: 'timestamp',
default: () => timeStamp,
onUpdate: timeStamp,
})
#IsDate()
lastUpdatedAt: Date;
}
And here is the new entity waiver templates, which has a ManyToOne relationship to the teams table, and exists on the new branch
#Entity({ name: 'waiverTemplates' })
#ObjectType()
export class WaiverTemplateEntity extends BaseEntity {
#Field(() => ID)
#PrimaryGeneratedColumn('uuid')
id: string;
#Field(() => TeamEntity)
#ManyToOne(
() => TeamEntity,
team => team.waiverTemplates,
{ onDelete: 'CASCADE', eager: true },
)
#JoinColumn()
team: Promise<TeamEntity>;
#Field(() => ID)
#Index()
#Column({ nullable: true })
teamId: string;
#Field()
#Column('json')
event: Event;
#Field()
#Column('json')
eventDate: EventDate;
#Field({ nullable: true })
#Column({ nullable: true })
includeEmergencyContact: boolean;
#Field({ nullable: true })
#Column({ nullable: true })
customerLabel: string;
#Field(() => CustomEntity, { nullable: true, defaultValue: [] })
#Column('jsonb', { nullable: true })
intensity: CustomEntity;
#Field(() => [CustomEntity], { nullable: true, defaultValue: [] })
#Column('jsonb', { nullable: true })
activities: CustomEntity[];
#Field({ defaultValue: waiverStatus.DRAFT, nullable: false })
#Column({ default: waiverStatus.DRAFT, nullable: false })
status: string;
#Field({ nullable: true })
#Column({ type: 'varchar', nullable: true })
title: string;
#Field({ nullable: true })
#Column({ nullable: true })
body: string;
#Field({ nullable: true })
#Column({ nullable: true, default: signatureDefaultContent })
signatureContent: string;
#Field(() => [String], { nullable: true })
#Column('simple-array', { nullable: true })
ageGroup: string[];
#Field(() => [AdditionalFields], { nullable: false, defaultValue: [] })
#Column('jsonb', { nullable: true })
additionalFields: AdditionalFields[];
#Field()
eventName: string;
}
And finally, here is the teams table, which also exists on the old branch. This is the code from the new branch, which contains a new OneToMany relationship to the WaiverTemplateEntity.
#Entity({ name: 'teams' })
#ObjectType()
export class TeamEntity extends BaseEntity {
#Field(() => ID)
#PrimaryGeneratedColumn('uuid')
id: string;
#Field()
#Column('varchar')
title: string;
#Field({ nullable: true })
#Column('varchar', { nullable: true })
taxID?: string;
#Field({ nullable: true })
#Column(simpleJSON, { nullable: true })
type: CustomEntity;
#Field({ nullable: true })
#Column('varchar', { nullable: true })
description?: string;
#Field(() => AccountEntity, { nullable: false })
#OneToOne(
() => AccountEntity,
accountEntity => accountEntity.organization,
{ nullable: true, onDelete: 'SET NULL' },
)
creator: AccountEntity;
#Field({ nullable: true })
#Column({ nullable: true })
creatorId: string;
#Field(() => BillingEntity, { nullable: true })
#OneToOne(
() => BillingEntity,
billingEntity => billingEntity.team,
{ cascade: true },
)
billingInformation: Promise<BillingEntity>;
#Field({ nullable: true })
#Column('varchar', { nullable: true })
photoURL?: string;
#Field({ defaultValue: false })
#Column({ default: false })
nonProfitFreemium: boolean;
#AfterLoad()
updateURLs(): void {
// add Prefix on retrieval
this.photoURL = this.photoURL
? `${getBucketPrefix(
AWS_BUCKETS_TYPES.ORGANIZATION_BUCKET_IMAGE,
'https://',
)}/${this.photoURL}`
: null;
}
#Field(() => [CardEntity], { nullable: true })
#OneToMany(
() => CardEntity,
cardEntity => cardEntity.holder,
{ cascade: true },
)
cards: Promise<CardEntity[]>;
#Field({ nullable: true, defaultValue: {} })
#Column(simpleJSON, { nullable: true })
location?: LocationEntity;
#Field({ nullable: true, defaultValue: {} })
#Column(simpleJSON, { nullable: true })
contact?: ContactEntity;
#Field({ nullable: true })
#Column({ nullable: true })
numberOfEmployees?: string;
#Field({ nullable: true })
#Column({ nullable: true })
stripeId?: string;
#Field()
#Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP(6)' })
#IsDate()
createdAt: Date;
#Field()
#Column({
type: 'timestamp',
default: () => 'CURRENT_TIMESTAMP(6)',
onUpdate: 'CURRENT_TIMESTAMP(6)',
})
#IsDate()
lastUpdatedAt: Date;
#Field(() => [InvitationEntity])
#OneToMany(
() => InvitationEntity,
invitationEntity => invitationEntity.team,
)
invitations: Promise<InvitationEntity[]>;
#Field(() => [WaiverEntity])
#OneToMany(
() => WaiverEntity,
waiver => waiver.team,
)
waivers: Promise<WaiverEntity[]>;
#Field({ nullable: true })
#Column({ default: () => 0 })
credits: number;
#Field({ nullable: true })
#Column({ default: () => false })
autoReload: boolean;
#Field({ nullable: true })
#Column({ default: () => 0 })
autoReloadAmount: number;
#Field({ nullable: true })
#Column({ default: () => 0 })
autoReloadMinAmount: number;
#Field({ nullable: true })
#Column({ type: 'float', default: 0.0 })
fixedWaiverPrice: number;
#Field(() => [TransactionEntity])
#OneToMany(
() => TransactionEntity,
transaction => transaction.team,
)
transactions: Promise<TransactionEntity[]>;
#Field(() => [WaiverTemplateEntity])
#OneToMany(
() => WaiverTemplateEntity,
waiverTemplate => waiverTemplate.team,
)
waiverTemplates: Promise<WaiverTemplateEntity[]>;
}
I know there's a lot of columns in the tables, but the ones to pay attention to are the relationships between the Teams table and the WaiverTemplates table. This is the only thing I changed in the entities, and what I think may be responsible for me being unable to connect to the previous database on this new branch. If you want to see my service, resolver, or modules, please ask. I don't believe they are causing any issues, because if I connect to a new database, everything compiles and works as intended, no errors are thrown. I'm really just looking for any insight on how to debug this problem.
If anyone is interested in this issue, I resolved the error finally today, at least in respects to the tables above.
When changing the PSQL database with TypeORM, it's better to either create or generate your own migration files with typeorm migration:generate -n [name of migration file] and then
typeorm migration:run. The generate command will auto generate an up and down SQL migration to run. You can use npx before this command or access the cli from node_modules, because just running the typeorm command gave me a command not found error.
I then looked inside the generated migration file, and lo and behold, the columns I was adding to the table were not set to be NULL, and thus I had the error of the values for those columns in the previous table being null. I had to manually add NULL to each of those columns for the code to compile. It's weird though, because I updated the entities to have {nullable: true} in the #Column decorators for those fields.
If anyone knows how to work better with changing relations in already existing tables with TypeORM and Nest, please reach out to me. I'm still working on writing the SQL manually for the migration file so that I can change the relationships in three other tables. I'm working with legacy code done poorly, so the relationships were wrong from the beginning.

how to limit typeorm join queries?

I'm new to typeorm, maybe someone can resolve my problem.
I'm using NestJS and TypeORM and have two tables (categories and talents). I wish to find a solution to limit typeorm join queries.
each category can have many talents in talent_worked and each talent can have many categories in working_categories.
i like to find all categories and there respected talent but i wish to get(limit) only five talents.
Talent:
#Entity('talents')
#Unique(['mobile'])
export class TalentsEntity extends BaseEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ nullable: true })
name: string;
#Column({ unique: true })
mobile: string;
#Column({ nullable: true })
email: string;
#Column({ select: false })
password: string;
#Column({ select: false })
salt: string;
#Column({ default: false })
isBlocked: boolean;
#Column({ default: true })
isActive: boolean;
// relation to categories model
#ManyToMany(
type => CategoriesEntity,
categoriesEntity => categoriesEntity.talent_worked,
{ eager: true },
)
#JoinTable({ name: 'talents_working_categories' })
working_categories: CategoriesEntity[];
}
Category:
#Entity('categories')
#Unique(['title'])
export class CategoriesEntity extends BaseEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ nullable: true })
title: string;
// relation to talents
#ManyToMany(
type => TalentsEntity,
talentsEntity => talentsEntity.working_categories,
{ eager: false },
)
talent_worked: TalentsEntity[];
}
here is my typeorm query so far:
const query = await this.createQueryBuilder('category');
query.leftJoinAndSelect('category.talent_worked', 'talent');
query.leftJoinAndSelect('talent.working_categories', 'talentCategories');
query.where('talent.isActive = :isActive AND talent.isBlocked = :isBlocked', { isActive: true, isBlocked: false});
if (categoryId) query.andWhere('category.id = :categoryId', { categoryId });
query.select([
'category.id',
'category.title',
'talent.id',
'talent.name',
'talentCategories.id',
'talentCategories.title',
]);
query.orderBy('category.created_at', 'ASC');
query.addOrderBy('talent.created_at', 'ASC');
return await query.getMany();