Closed SergeEsmanovich closed 6 years ago
Can you paste full definition of both sides of relation classes?
I've added better typeorm example that covers exactly this case.
Seems like Family
class is not decorated with @ObjectType
eg.
@ObjectType() // <-- do you have Family class decorated?
class Family {
// ...
}
import {Entity} from 'typeorm/decorator/entity/Entity';
import {BaseEntity, ManyToOne, PrimaryGeneratedColumn} from 'typeorm';
import {Profile} from './Profile';
import {FamilyRank} from './FamilyRank';
import {Childhood} from './Childhood';
import {FamilyStatus} from './FamilyStatus';
import {FamilyTragedy} from './FamilyTragedy';
import {Parents} from './Parents';
import {Field, ObjectType} from 'typegql';
@Entity()
@ObjectType()
export class Family extends BaseEntity{
@PrimaryGeneratedColumn()
@Field()
id: number;
@ManyToOne(type => Profile, profile => profile.family)
@Field()
profile: Profile;
@ManyToOne(type => FamilyRank, familyRank => familyRank.family)
@Field()
familyRank: FamilyRank;
@ManyToOne(type => Childhood, childhood => childhood.family)
@Field()
childhood: Childhood;
@ManyToOne(type => FamilyStatus, familyStatus => familyStatus.family)
@Field()
familyStatus: FamilyStatus;
@ManyToOne(type => FamilyTragedy, familyTragedy => familyTragedy.family)
@Field()
familyTragedy: FamilyTragedy;
@ManyToOne(type => Parents, parents => parents.family)
@Field()
parents: Parents;
}
import {BaseEntity, Column, OneToMany, PrimaryGeneratedColumn} from 'typeorm';
import {Entity} from 'typeorm/decorator/entity/Entity';
import {Family} from './Family';
import {Field, ObjectType} from 'typegql';
@Entity()
@ObjectType()
export class Childhood extends BaseEntity {
@PrimaryGeneratedColumn()
@Field()
id: number;
@Column()
@Field()
name: string;
@OneToMany(type => Family, family => family.childhood)
@Field()
family: Family[];
}
Seems you have circular relationship (Childhood > Family > Childhood > Family) etc. In such case, you have to define type as function. (http://siawyoung.com/coding/javascript/circular-references-graphql-type-definitions.html)
Try to modify:
@ManyToOne(type => Childhood, childhood => childhood.family)
@Field()
childhood: Childhood;
to
@ManyToOne(type => Childhood, childhood => childhood.family)
@Field({ type: () => Childhood })
childhood: Childhood;
Also change
@OneToMany(type => Family, family => family.childhood)
@Field()
family: Family[];
to
@OneToMany(type => Family, family => family.childhood)
@Field({ type: () => [Family] })
family: Family[];
And let me know if that helps.
Note that if you use array types (eg. Family[]
) you'd have to set type manually anyway as typescript is not able to guess type of array item.
it works but not quite. My query
{
getFamilies{
id
childhood {
id
name
}
}
}
Family:
@Entity()
@ObjectType()
export class Family extends BaseEntity {
@PrimaryGeneratedColumn()
@Field()
id: number;
@ManyToOne(type => Childhood, childhood => childhood.family)
@Field({type: () => Childhood})
childhood(): Childhood {
return Childhood.findOneById(1);
};
...
}
Childhood:
@Entity()
@ObjectType()
export class Childhood extends BaseEntity {
@PrimaryGeneratedColumn()
@Field()
id: number;
@Column()
@Field()
name: string;
@OneToMany(type => Family, family => family.childhood)
@Field({type: () => [Family]})
family: Family[];
}
Schema:
@Schema()
class ApiSchema {
@Query({type: [Family]})
async getFamilies(): Promise<Family[]> {
return await Family.find();
}
}
Response:
{
"data": {
"getFamilies": [
{
"id": 1,
"childhood": {
"id": 1,
"name": "Spent on the Street, with no adult supervision"
}
}
]
}
}
I do not understand how to get here ID
@ManyToOne(type => Childhood, childhood => childhood.family)
@Field({type: () => Childhood})
childhood(): Childhood {
return Childhood.findOneById(1);
};
@korolariya
But sometimes you want to know what is the "profile id" of this user without loading the whole profile for this user. To do this you just need to add another property to your entity with @Column named exactly as the column created by your relation. http://typeorm.io/#/relations-faq/how-to-use-relation-id-without-joining-relation
You can take a look at this in my simple TypeORM example: https://github.com/19majkel94/type-graphql/blob/master/examples/typeorm-basic-usage/resolvers/rate-resolver.ts#L16
However the easier approach is to use lazy relations and let TypeORM fetch this automatically: https://github.com/19majkel94/type-graphql/blob/master/examples/typeorm-lazy-relations/entities/rate.ts
@korolariya you don't need to define function that returns your Childhood
s. Typeorm is handling it by itself.
So basically you could simply
@ManyToOne(type => Childhood, childhood => childhood.family)
@Field({type: () => Childhood})
childhood: Childhood;
If you'd need to add some custom logic you could do this like:
@Field({type: () => Childhood})
async childhood() {
return Childhood.createQueryBuilder().relation("family").of(this).loadOne();
// or some custom logic
};
But it might not be needed propably in your case. In case you'd like to learn more about relational queries: http://typeorm.io/#/relational-query-builder
Typeorm is handling it by itself.
@pie6k Only with lazy relations. Normally you need to overfetch them in main query or fetch manually in field resolver. Try that by yourself by creating more advanced TypeORM example than the basic one.
Thanks @19majkel94 , I've made typeorm example more advanced and added relations example. You can check it out @korolariya .
Note that relation is marked as lazy
so it can be fetched when graphql will need it.
@19majkel94, @pie6k It awesome, thanks. Everything works, I will continue to study.
I try