Cannot read properties of undefined reading 'getEntityValue' typeorm - postgresql

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.

Related

How to Implement Typeorm Entity Array of Object

I want to achieve this output:
{
.....,
dependants: [{name: 'john', age: 29},{name: 'doe', age: 17}]
}
I have an entity like this:
class PartnerStaff extends BaseEntity {
constructor(
id: string,
company: string,
branch: string,
dependants: DependantDto[],
) {
super();
this.staffId = id;
this.company = company;
this.branch = branch;
this.dependants = dependants;
}
#PrimaryGeneratedColumn('increment')
id!: number;
#Column({
unique: true,
nullable: true,
})
staffId!: string;
#Column({
nullable: true,
name: 'company',
})
company!: string;
#Column()
branch!: string;
#Column('json', {nullable: true})
dependants?: DependantDto[];
}
And my dependants dto:
class DependantDto {
#IsString()
#IsNotEmpty({ message: 'dependant name is required' })
readonly name!: string;
#IsString()
#IsNotEmpty({ message: 'dependant age is required' })
readonly age!: number;
}
I am getting dependants: ['string'] on swagger.
I have tried these but still not working...
#Column('jsonb', {nullable: true})
#Column({type: 'array', nullable: true})
I was able to solve it this way....
#Column({type: 'json'})
dependants: DependantsDto[];
Then in my PartnerStaffDto, I did ...
#IsOptional()
#ApiModelProperty({
isArray: true
})
dependants: DependantsDto[];
So now I get what i was expecting ealier dependants: [{name: '', age: 0}]

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?

No Column ({nullable:true, default: 0}) added in production mode

I have a NestJS backend, with postgresql db deploy on digitalocean, I have updated entities, added several columns with nullable and default values, builded several times but tables are not updated.. Can anybody help? :( shps_id and verified are newly added. It works in development mode .. dropping little code snippet:
#Entity()
export class User extends BaseEntity {
#PrimaryGeneratedColumn()
id: number;
#Column({ unique: true })
email: string;
#Column({ name: 'first_name' })
first_name: string;
#Column({ name: 'last_name' })
last_name: string;
#Column({ nullable: true })
salt: string;
#Column()
password: string;
#Column({default: 0})
verified: number
#Column({nullable: true, default: null})
shps_id: 'string'
#Column({ nullable: true })
role: string;
} ```

Get entities within 100km with postgresql and typeorm ordered

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();

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();