I a newbie with type-graphql and I have this weird issue of field resolvers not working.
I'm using a stack of:
- typescript(3.9.5)
- type-graphql(1.0.0)
- typeorm(0.2.25)
- apollo(2.16.0).
Whenever I run my typescript (using ts-node) everything works well, but when I use the compiled js version with express, the queries work only with simple db fields, but fieldResolvers don't work at all and in the end I get "Cannot return null for non-nullable field". The funny thing is that the field resolvers are sibling of query resolvers in the same @Resolver class. the queries get fired (placed a console log) but the field resolvers never do. anyone have a clue?
here are some snippets from the code:
@Entity()
@ObjectType()
export class Member extends BaseEntity {
@Field(() => ID)
@PrimaryGeneratedColumn()
id: string;
@UseForSearch()
@UseAsTitle()
@Field(() => String)
@IsEmail()
@Column({ type: 'varchar', unique: true })
email: string;
@Field(() => [Item])
@OneToMany(type => Item, item => item.member)
items?: Item[];
@OneToMany(type => Review, review => review.member)
reviews?: Review[];
@Field(() => Number)
itemsCount: number;
}
@Entity()
@ObjectType()
export class Item extends BaseEntity {
@Field(() => ID)
@PrimaryGeneratedColumn()
id: string;
@ManyToOne(type => Category, category => category.items)
@JoinColumn({ name: 'categoryId' })
@Field(() => Category)
category?: Category;
@Field(() => String, { nullable: true })
@Column({
nullable: true,
})
name: string;
@ManyToOne(type => Member, member => member.items)
@JoinColumn({ name: 'memberId' })
@Field(() => Member)
member?: Member;
@Field(() => ID)
@Column('int', { nullable: true })
public memberId: number | null;
}
import { Resolver, Query, FieldResolver, Root, Ctx, Arg } from 'type-graphql';
import { getRepository, Repository } from 'typeorm';
import { Item } from '../entity';
import { Member } from '../entity/member';
@Resolver(of => Member)
export class MemberResolver {
constructor(private itemsRepository: Repository<Item>) {
this.itemsRepository = getRepository(Item);
}
@Query(() => [Member])
members() {
console.log('in members query');
return Member.find();
}
@FieldResolver()
async items(@Root() member: Member) {
return await this.itemsRepository.find({ where: { memberId: member.id } });
}
@FieldResolver()
async itemsCount(@Root() member: Member) {
console.log('in itemsCount resolver');
return this.itemsRepository.count({ where: { memberId: member.id } });
}
query {
members {
email
itemsCount
}
}
{
"errors": [
{
"message": "Cannot return null for non-nullable field Member.itemsCount.",
"locations": [
{
"line": 4,
"column": 5
}
],
"path": [
"members",
0,
"itemsCount"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"Error: Cannot return null for non-nullable field Member.itemsCount.",
" at completeValue (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:599:13)",
" at completeValueCatchingError (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:534:19)",
" at resolveField (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:465:10)",
" at executeFields (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:297:18)",
" at collectAndExecuteSubfields (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:752:10)",
" at completeObjectValue (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:742:10)",
" at completeValue (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:630:12)",
" at completeValue (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:596:21)",
" at completeValueCatchingError (/Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:534:19)",
" at /Users/admin/tackar/clampa/clampa-server/node_modules/graphql/execution/execute.js:655:25"
]
}
}
}
],
"data": null
}