I am trying to setup my graphql resover to handle an array of objects but cant get the @Args decorator configured.
I created my own ArgsType
import { ArgsType, Field, Int, ObjectType } from '@nestjs/graphql';
@ArgsType() // to be used as type in the resolver
@ObjectType() // for schema generation
export class Club {
@Field(type => String)
president: string;
@Field(type => Int)
members?: number;
}
Resolver with adding a single Club works just fine!
@Query(() => Int)
async addClub(@Args() club: Club) {
// handle stuff
}
but if I want to give an array of Club like this
@Query(() => Int)
async addClubs(@Args({name: 'clubs', type: () => [Club]}) clubs: Array<Club>) {
// handle stuff
}
this thows an error when nest is starting up
UnhandledPromiseRejectionWarning: Error: Cannot determine a GraphQL input type for the "clubs". Make sure your class is decorated with an appropriate decorator.
although I am able to use an array of Strings like this
@Query(() => [String])
async addStrings(@Args({ name: 'clubs', type: () => [String], }) clubs: Array<string>) {
// handle stuff
}
I am pretty sure there should be an easy solution, but cant figure out where to go from here.
What is the input type? The input type in a GraphQL schema is a special object type that groups a set of arguments together, and can then be used as an argument to another field. Using input types helps us group and understand arguments, especially for mutations.
Resolvers provide the instructions for turning a GraphQL operation (a query, mutation, or subscription) into data. They return the same shape of data we specify in our schema -- either synchronously or as a promise that resolves to a result of that shape. Typically, you create a resolver map manually.
Enumeration types are a special kind of scalar that is restricted to a particular set of allowed values (read more here).
GraphQL is a powerful query language for APIs and a runtime for fulfilling those queries with your existing data. It's an elegant approach that solves many problems typically found with REST APIs. For background, we suggest reading this comparison between GraphQL and REST.
According to the error,
Cannot determine a GraphQL input type for the "clubs". Make sure your class is decorated with an appropriate decorator
You're trying to use Club
class as a GraphQL input type while it is already an object type (According to @ObjectType
annotation you use).
Solution 1:
I would suggest you write a separate GraphQL input type like below (not tested). This is cleaner and less coupled if you need to separate the way you treat input and output of Club
.
import { InputType, Field } from '@nestjs/graphql';
@InputType()
export class ClubInput {
@Field()
president: string;
@Field()
members?: number;
}
Then in your resolver, you can use it like below.
@Query(() => Int)
async addClubs(@Args({name: 'clubs', type: () => [ClubInput]}) clubs: Array<ClubInput>) {
// handle stuff
}
Solution 2:
But if you really need to use the same class for both purposes, you could try to create both input and object types with the same Club
name. The name of the object type is by default the name of the class. So you need to provide the name explicitly to avoid conflict.
import { Field, Int, ObjectType, InputType } from '@nestjs/graphql';
@InputType("ClubInput")
@ObjectType("ClubType")
export class Club {
@Field(type => String)
president: string;
@Field(type => Int)
members?: number;
}
Now your Club
has different names for input and object types. Then in your resolver, you can use it like below.
@Query(() => Int)
async addClubs(@Args({name: 'clubs', type: () => [ClubInput]}) clubs: Array<ClubInput>) {
// handle stuff
}
Note: In this solution, you need to make sure that Club
will never contain fields that express circular references or references to interfaces and unions. If that is going to happen, you will have to move to Solution 1, else this will make your input throw an error.
The take away is that in Typescript GraphQL, InputType
and ObjectType
are two different concepts and we need to use it properly to avoid any issues.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With