I have try with following code but i will got only first table record, there are missed second table info.
@property({
name: 'name',
type: 'string',
})
name: string;
@hasOne(() => Info)
infos: Info;
@property({
type: 'number',
id: true,
required: true,
})
id: number;
@belongsTo(() => Person)
personId?: number;
export class PersonRepository extends DefaultCrudRepository<Person,typeof Person.prototype.id>
{
public readonly infos: HasOneRepositoryFactory<Info,typeof Person.prototype.id>;
constructor(@inject('datasources.db') dataSource: DbDataSource,
@repository.getter('InfoRepository')
getInfoRepository: Getter<InfoRepository>,) {
super(Person, dataSource);
this.infos = this._createHasOneRepositoryFactoryFor('infos',getInfoRepository);
}
}
But when i will call the api using explorer they have return following schema
Example Value
Schema
[ {
"id": 0,
"name": "string"
}]
Is there any solution for this?
@raymondfeng Can you please help me in this if you have brief idea ?
Hi @drplutus, please create a small app reproducing the issue per our bug reporting instructions.
@b-admike I think you are most familiar with relations, could you PTAL?
I have create one simple api which is going to fetch the data from database(Mysql).
Table 1 : person (id, person_name )
Table 2 : info (id, person_id, address)
Table 1 is belongs to table one. Suppose we fetch data from person table then respective info table data will fetch.
import { Info } from "./info.model";
import { Entity, model, property, hasMany, hasOne } from '@loopback/repository';
@model()
export class Person extends Entity {
@property({ type: 'number', id: true, required: true, })
id: number;
@property({ person_name: 'name', type: 'string', })
person_name: string;
@hasOne(() => Info, { keyTo: 'person_id' })
infos: Info[];
constructor(data?: Partial<Person>) {
super(data);
}
}
import { Entity, model, property, belongsTo } from '@loopback/repository';
import { Person } from "./person.model";
@model()
export class Info extends Entity {
@property({ type: 'number', id: true, required: true, })
id: number;
@property({ address: 'name', description: "Info name.", type: 'string', })
address: string;
@belongsTo(() => Person)
person_id: number;
constructor(data?: Partial<Info>) {
super(data);
}
}
import { DefaultCrudRepository, repository, juggler, HasManyRepositoryFactory, HasOneRepositoryFactory } from '@loopback/repository';
import { InfoRepository } from './info.repository';
import { Person, Info } from '../models';
import { DbDataSource } from '../datasources';
import { inject, Getter } from '@loopback/core';
export class PersonRepository extends DefaultCrudRepository<Person, typeof Person.prototype.id> {
public infos: HasOneRepositoryFactory<Info, typeof Person.prototype.id>;
constructor(
@inject('datasources.db') dataSource: DbDataSource, @repository.getter('InfoRepository')
protected infoRepositoryGetter: Getter<InfoRepository>
) {
super(Person, dataSource);
this.infos = this._createHasOneRepositoryFactoryFor('infos', infoRepositoryGetter);
}
}
Api code which is called from controller
@get('/people', {
responses: {
'200': {
description: 'Array of Person model instances',
content: {
'application/json': {
schema: { type: 'array', items: { 'x-ts-type': Person } },
},
},
},
},
})
async find(
@param.query.object('filter', getFilterSchemaFor(Person)) filter?: Filter): Promise<Person[]> {
return await this.personRepository.find(filter);
}
It will return error : 500 TypeError: Cannot read property 'target' of undefined
Just i want to get person information with address.
First of all, filter.include is not supported in LB4 yet, see https://github.com/strongloop/loopback-next/issues/1352 and the spike/proof-of-concept in https://github.com/strongloop/loopback-next/pull/2124.
But when i will call the api using explorer they have return following schema
Generating the correct schema for different CRUD endpoints is a bit tricky:
I think we need two schemas, possibly even two TypeScript models/interfaces. Please refer to discussion in https://github.com/strongloop/loopback-next/pull/2124 for more details.
/cc @jannyHou @b-admike
It will return error : 500 TypeError: Cannot read property 'target' of undefined
Sorry, I don't have bandwidth to re-create a working LB4 application from your instructions and thus I cannot look into details of the error you are encountering. Can you please follow the instructions in https://loopback.io/doc/en/contrib/Reporting-issues.html#loopback-4x-bugs and provide us with a LB4 app that we can simply git clone and then run to reproduce the problem.
try,
@hasOne(() => Info)
infos: Info[];
instead of
@hasOne(() => Info, { keyTo: 'person_id' })
infos: Info[];
may be it will work
I spot some problems that might crash the app:
hasOne property is an object instead of an array( has one). @hasOne(() => Info, { keyTo: 'person_id' })
infos: Info; // here
person_id in your case. default is personId). @hasOne(() => Info, { keyTo: 'person_id' })
infos: Info;
in Info.model:
@belongsTo(() => Customer, {name: 'person'}) // `person` is the name of your belongsTo relation name
person_id?: number;
Ref: HasOne relation customizing name
Also, we support inclusion for relations now :D check out Querying related models on our site!
Feel free to re-open the issue if it's not solved yet. Thanks!
this works for me
@model({
settings: {
foreignKeys: {
fk_todo_todoListId: {
name: 'fk_todo_todoListId',
entity: 'TodoList',
entityKey: 'id',
foreignKey: 'todolistid',
},
},
},
})
export class Todo extends Entity {
//etc.
}
https://loopback.io/doc/en/lb4/todo-list-tutorial-sqldb.html#specify-the-foreign-key-constraints-in-todo-model
Most helpful comment
I have create one simple api which is going to fetch the data from database(Mysql).
Table 1 is belongs to table one. Suppose we fetch data from person table then respective info table data will fetch.
person.model.ts:
info.model.ts:
person.repository.ts
Api code which is called from controller
It will return error : 500 TypeError: Cannot read property 'target' of undefined
Just i want to get person information with address.