NestJS - TypeORM - ManyToOne Entity is undefined
Asked Answered
C

2

6

I am trying to link to entities Child & Client

So I have created 2 entities :

// src/children/child.entity.ts

@Entity()
export class Child extends BaseEntity {

  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstname: string;

  @Column()
  lastname: string;

  @ManyToOne(type => Client, client => client.children, { eager: false })
  client: Client

  @Column()
  clientId: number;
}

and

// src/clients/client.entity.ts

@Entity()
export class Client extends BaseEntity {

  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstname: string;

  @Column()
  lastname: string;

  @OneToMany(type => Child, child => child.client, { eager: true })
  children: Child[];

}

I'm able to create a client & a child. When I get a client, I can retrieve all his children.

But I am not able to retrieve a client with a child :

For example, in children.controller.ts

enter image description here

When I visit http://locahost:3000/children/1/parent

I got on the console :

enter image description here

I am really stuck because I don't know how to solve this issue.

Here is children.module.ts

import { Module } from '@nestjs/common';
import { ChildrenController } from './children.controller';
import { ChildrenService } from './children.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ChildRepository } from './child.repository';
import { ClientRepository } from 'src/clients/client.repository';
import { ClientsService } from 'src/clients/clients.service';
import { Client } from 'src/clients/client.entity';

@Module({
  imports: [
    TypeOrmModule.forFeature([ChildRepository, ClientRepository, Client]),
  ],
  controllers: [ChildrenController],
  providers: [ChildrenService, ClientsService]
})
export class ChildrenModule {}

Here is typeorm.config

import { TypeOrmModuleOptions } from '@nestjs/typeorm';

export const typeOrmConfig: TypeOrmModuleOptions = {
  type: 'postgres',
  host: 'localhost',
  port: 5432,
  username: 'myusername',
  password: '',
  database: 'mydatabase',
  entities: [__dirname + '/../**/*.entity.{js,ts}'],
  synchronize: true,
}

Edit 1 :

children.controller.ts

// src/children/children.controller.ts

@Controller('children')
export class ChildrenController {

  constructor(
    private childrenService: ChildrenService,
    private clientsService: ClientsService
  ) {}

  @Get('/:id')
  async getChild(id: number): Promise<Child> {
    return await this.childrenService.getChild(id);
  }
}

children.service.ts

// src/children/children.service.ts

@Injectable()
export class ChildrenService {
  constructor(
    @InjectRepository(ChildRepository)
    private childRepository: ChildRepository,
    @InjectRepository(ClientRepository)
    private clientRepository: ClientRepository
  ) {}

  async getChild(id: number): Promise<Child> {
    return await this.childRepository.findOne(id)
  }
}

Thanks for you help πŸ˜€

Check answered 17/5, 2020 at 15:45 Comment(2)
what code contains your getChild method? – Voguish
I have added the code for getChild to retrieve the child into the database. – Check
V
10

It seems to me that you forgot add @JoinColumn() on ManyToOne side of this relation. Try enhance your code in this way


@Entity()
export class Child extends BaseEntity {

  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstname: string;

  @Column()
  lastname: string;

  @ManyToOne(type => Client, client => client.children, { eager: false })
  @JoinColumn()
  client: Client

  @Column()
  clientId: number;
}

Also, pay attention on eager parameter. If it set as true this relation will be loaded automatically even you didn't require it manually, otherwise you have to specify that you want relation to be loaded. Try enhance children.service.ts like this:

  async getChild(id: number): Promise<Child> {
    return await this.childRepository.findOne(id, {
      relations: ['client']
    })
  }

or you can set this relation as eager and it will be loaded automatically every time when you load Child

  @ManyToOne(type => Client, client => client.children, { eager: true })
  @JoinColumn()
  client: Client
Voguish answered 17/5, 2020 at 17:33 Comment(5)
thanks for your answer ! I still have the issue. I have a restart the server after the update. Not working + I have remove database tables and still not working. – Check
after you changed database you need generate migration and apply it – Voguish
I am sorry but I dont how to proceed it. I thought with synchronize: true everything will be auto-updated – Check
You're right about synchronize: true. I've added one more advice to my answer, try it – Voguish
adding { relations: ['client'] } solved the issue ! Thanks a lot ! – Check
P
0

as @Yevhenii mention, you forgot to add JoinColumn but you have to specify the client column:

    @Entity()
export class Child extends BaseEntity {

  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstname: string;

  @Column()
  lastname: string;

  @ManyToOne(()=> Client, (client) => client.children, { eager: false })
  @JoinColumn([{ name: "clientId", referencedColumnName: "id" }])
  client: Client

  @Column()
  clientId: number;
}

Don't hesitate to tell me the result.

Promote answered 18/5, 2020 at 9:55 Comment(1)
Thanks for you answer. The solution given by Yevhenii is working well. – Check

© 2022 - 2024 β€” McMap. All rights reserved.