Search code examples
node.jsfrontendbackendv4l2loopback

How can i do the join of two table in loopback4


I have created below mention controller,model and repository in my code. Please have look.

I have developed below mention code but still not able to perform the join operation.

I am going to join two table that is person and info table.

 - Info table having one foreign key which is belong to person table.
 
 - Person table: id, name, status
 
 - Info table : id, person_id , name , status

I have also create repository,model and controller file for info and person.

Person Repository ( person.repository.ts)

) {
  super(Person, dataSource);
  this.infos = this._createHasOneRepositoryFactoryFor(
    'info',
    getInfoRepository,
 );
}

Person Module ( person.module.ts)

 @hasOne(() => Info)
    infos?: Info;
 
 constructor(data?: Partial<Person>) {
  super(data);
 }

Info Module (info.module.ts)

 @belongsTo(() => Person)
 personId: number;

 constructor(data?: Partial<Info>) {
    super(data);
 }

It show me error like this Unhandled error in GET /people/fetchfromtwotable?filter[offset]=0&filter[limit]=10&filter[skip]=0: 500 TypeError: Cannot read property 'target' of undefined

Is there any idea about join?


Solution

  • drp, Thanks for sharing your models. My post got deleted because I am just starting out and needed to ask for more info which seems strange. ANYWAY, Try to change this line:

     this.infos = this._createHasOneRepositoryFactoryFor(
    'info',
    getInfoRepository
    );
    

    to

     this.infos = this._createHasOneRepositoryFactoryFor(
    'infos',
    getInfoRepository,
    );
    

    The framework cannot find the 'info' relation on the model because you called the property 'infos'

    Here is my example that currently works for me (running latest lb4 and postgres):

    User.model.ts

    import { model, property, hasOne, Entity } from '@loopback/repository';
    import { Address } from './address.model';
    
    @model()
    export class User extends Entity {
    
      constructor(data?: Partial<User>) {
        super(data);
      }
    
      @property({ id: true })
      id: number;
      @property()
      email: string;
      @property()
      isMember: boolean;
    
      @hasOne(() => Address, {})
      address?: Address;
    }
    

    Address.model.ts:

    import { model, property, belongsTo, Entity } from '@loopback/repository';
    import { User } from '../models/user.model';
    
    @model()
    export class Address extends Entity {
    
      constructor(data?: Partial<Address>) {
        super(data);
      }
    
      @property({ id: true })
      id: number;
    
      @property()
      street1: string;
      @property()
      street2: string;
      @property()
      city: string;
      @property()
      state: string;
      @property()
      zip: string;
    
      @belongsTo(() => User)
      userId: number;
    
    }
    

    User.repository.ts:

    import { HasOneRepositoryFactory, DefaultCrudRepository, juggler, repository } from '@loopback/repository';
    import { User, Address } from '../models';
    import { PostgresDataSource } from '../datasources';
    import { inject, Getter } from '@loopback/core';
    import { AddressRepository } from '../repositories'
    
    export class UserRepository extends DefaultCrudRepository<
      User,
      typeof User.prototype.id
      > {
    
      public readonly address: HasOneRepositoryFactory<Address, typeof User.prototype.id>;
    
      constructor(
        @inject('datasources.postgres')
        dataSource: PostgresDataSource,
    
        @repository.getter('AddressRepository')
        protected getAccountRepository: Getter<AddressRepository>,
    
      ) {
        super(User, dataSource);
        this.address = this._createHasOneRepositoryFactoryFor('address', getAccountRepository);
    
      } // end ctor
    
    
    }
    

    User.controller.ts (abridged for length):

      @get('/users/{id}/address')
      async getAddress(
        @param.path.number('id') userId: typeof User.prototype.id,
        @param.query.object('filter', getFilterSchemaFor(Address)) filter?: Filter,
      ): Promise<Address> {
    
        return await this.userRepository
          .address(userId).get(filter);
      }
    

    Hope this helps.

    Good luck!