Search code examples
typeormnestjs-typeorm

Typeorm eager load with a condition for the children


I have two entities, one parent and one child. There is a OneToMany relation with eager enabled.

When I get the parent entity I would like to load only children with the property deleted to false. For now it's returning all children.

Here are my files:

@Entity()
export class Parent {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ default: false })
  deleted: boolean;

  @OneToMany(() => Child, (child) => child.parent, {
    cascade: true,
    eager: true,
  })
  children: Child[];
}
@Entity()
export class Child{
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ default: false })
  deleted: boolean;

  @ManyToOne(() => Parent, (parent) => parent.children)
  parent: Parent;
}
@Injectable()
export class ParentsService {
  constructor(
    @InjectRepository(Parent)
    private parentRepository: Repository<Parent>,
  ) {}

  findAll(): Promise<Parent[]> {
    return this.parentRepository.find({ where: { deleted: false } });
  }
}

I tried to change my findAll like this, but then if my parent as one child deleted, the parent wont be retrieved :

  findAll(): Promise<Parent[]> {
    return this.parentRepository.find({ where: { deleted: false, children:{deleted:false} } });
  }

Solution

  • I guess, the best way to do that, will be to use @DeleteDateColumn(), as soft-delete is already inside typeorm.

    @Entity()
    export class Child {
        @PrimaryGeneratedColumn()
        id: number;
    
        @DeleteDateColumn()
        deletedAt: Date;
    
        @ManyToOne(() => Parent, (parent) => parent.children)
        parent: Parent;
    }
    

    You can soft-remove your entity

    this.parentRepository.softRemove(child);
    

    And you don't need any where clause.

    findAll(): Promise<Parent[]> {
        return this.parentRepository.find();
      }
    

    To find with deleted

    this.parentRepository.find({ withDeleted: true });