'How to save Column with @Afterload , Nested Relations TypeORM

I want to put the number of posts in my user profile entity.

  • user_profile.entity.ts
@Entity()
@Unique(['username'])
export class UserProfile {
  /** Columns */
  @PrimaryGeneratedColumn('uuid')
  readonly id: string;
 
  @Column('timestamptz')
  @CreateDateColumn()
  readonly created_at: Date;
 
  @Column('timestamptz')
  @UpdateDateColumn()
  readonly updated_at: Date;
 
  @ApiProperty()
  @Column({ length: 255 })
  @IsString()
  @Length(3, 50)
  username: string;
 
  @Column()
  post_count: number;
 
  @ApiProperty({ readOnly: true })
  @Column('uuid')
  @IsUUID('4')
  user_id: string;
 
  @ApiProperty({ readOnly: true })
  @Column({ default: 0, nullable: true })
  @IsOptional()
  exp?: number;
 
  @ApiProperty({ readOnly: true })
  @Column({ default: 1, nullable: true })
  @IsOptional()
  level?: number;
 
  /** Relations */
  @OneToOne((type) => User, (user) => user.profile, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'user_id', referencedColumnName: 'id' })
  user: User;
 
  // ** Hooks
 
  @AfterLoad()
  updatePostCount() {
this.post_count = this.user.posts.length;
  }
}

  • user.entity.ts
@Entity()
@Unique(['email'])
@Check(`
  COALESCE((provider = 'local')::integer, 0) 
  + 
  COALESCE(LENGTH(social_id::text)::boolean::integer, 0)
  = 1
`)
export class User {
  /** Columns */
 
  @ApiProperty()
  @PrimaryGeneratedColumn('uuid')
  readonly id: string;
 
  @ApiProperty()
  @Column('timestamptz')
  @CreateDateColumn()
  readonly created_at: Date;
 
  @ApiProperty()
  @Column('timestamptz')
  @UpdateDateColumn()
  readonly updated_at: Date;
 
  @ApiProperty()
  @Column({ length: 255 })
  @IsEmail()
  email: string;
 
  /** Relations */
 
  @OneToMany((type) => Post, (post) => post.author)
  posts: Post[];
 
  @ApiProperty()
  @OneToOne((type) => UserProfile, (userProfile) => userProfile.user, {
    cascade: true,
  })
  profile: UserProfile;
 
  @AfterLoad()
  asdfasdf() {
    console.log('유저 entity :');
  }
}

  • post.entity.ts
@Entity()
export class Post {
  /** Columns */
 
  @PrimaryGeneratedColumn('uuid')
  readonly id: string;
 
  @Column('timestamptz')
  @CreateDateColumn()
  readonly created_at: Date;
 
  @Column('timestamptz')
  @UpdateDateColumn()
  readonly updated_at: Date;
 
  @ApiProperty()
  @Column({ length: 255 })
  @IsString()
  title: string;
 
  @ApiProperty()
  @Column('text')
  @IsString()
  contents: string;
 
  @ApiProperty({ readOnly: true })
  @Column('uuid')
  @IsUUID('4')
  user_id: string;
 
  /** Relations */
  @ManyToOne((type) => User, (user) => user.posts, {
    cascade: true,
    // eager: true,
    onDelete: 'CASCADE',
  })
  @JoinColumn({ name: 'user_id', referencedColumnName: 'id' })
  author: User;
}

  • users.service.ts

  async getMyUser(user_id: string) {
    const test = await this.userProfileRepository
      .createQueryBuilder('user_profile')
      .leftJoinAndSelect('user_profile.user', 'user')
      .leftJoinAndSelect('user.posts', 'posts')
      .where('user.id = :id', { id: user_id })
      .getOne();

    return test;
  }

  async getUserProfile(user_id: string): Promise<UserProfileResponseDto> {
    try {
      const user = await this.userRepository
        .createQueryBuilder('user')
        .leftJoinAndSelect('user.profile', 'user_profile')
        .leftJoinAndSelect('user.followers', 'followers')
        .leftJoinAndSelect('user.following', 'following')
        .leftJoinAndSelect('user.posts', 'posts')
        .where('user.id = :id', { id: user_id })
        .getOne();

      if (!user) {
        throw new Error();
      }
      return {
        profile: user.profile,
        followers: user.followers.length,
        following: user.following.length,
        posts: user.posts.length,
      };
    } catch (err) {
      throw new BadRequestException('Invalid user_id');
    }
  }

In user_profile entity, I used @Afterload,

When I use userPrifileRepository(getMyUser), the output is good, but if I use userRepository(getUserProfile), it doesn't come out. (this.user or this.user.posts.length was printed as undefined.)

And even if the output was good, it could not be saved. this.post_count = this.user.posts.length



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source