#Problems reading Args when creating a GraphQL mutation

16 messages · Page 1 of 1 (latest)

stable linden
#

I've been following along with the code first approach to create a GraphQL mutation for basic auth as documented on: https://docs.nestjs.com/graphql/mutations

This is what I have so far...

// login-input.dto.ts
@InputType('LoginInput')
export class LoginInputDTO {
  @Field()
  @IsEmail()
  email!: string

  @Field(() => String)
  @IsString()
  password!: string
}
// login-response.dto.ts
@ObjectType('LoginResponse')
export class LoginResponseDTO {
  @Field()
  accessToken!: string
}
// auth.resolver.ts
@Resolver()
export class AuthResolver {
  @Mutation(() => LoginResponseDTO)
  async login(@Args('input') input: LoginInputDTO): Promise<LoginResponseDTO> {
    console.log(input)
  }
}

However, input is always undefined. I stumbled across this post: https://stackoverflow.com/questions/69165638/graphql-mutation-and-query-cannot-read-property-of-undefined

So I updated my mutation signature to be like this:

// auth.resolver.ts
type LoginInputType = {
  input: LoginInputDTO
}

@Resolver()
export class AuthResolver {
  @Mutation(() => LoginResponseDTO)
  async login(_: any, @Args('input', { type: () => LoginInputDTO }) { input }: LoginInputType): Promise<LoginResponseDTO> {
    console.log(input)
  }
}

This now works, but I'm confused as to why the example from the documentation didn't work for me. I'm not happy with the extra LoginInputType type that I need to create, so any help to understand how I can get the documented code to work would be much appreciated!

pseudo finch
#

How are you running your app? Is it the default, or you maybe switched to SWC, etc.?

stable linden
#

I'm developing locally using yarn: yarn start:dev

pseudo finch
#

Could you share your nest-cli.json?

candid oarBOT
#

Please run the command npx -y @nestjs/cli info and paste the output in a code block. This will help us determine if there is a version issue in your packages and which version of nest we are triaging.

stable linden
stable linden
# candid oar Please run the command `npx -y @nestjs/cli info` and paste the output in a code ...
 _   _             _      ___  _____  _____  _     _____
| \ | |           | |    |_  |/  ___|/  __ \| |   |_   _|
|  \| |  ___  ___ | |_     | |\ `--. | /  \/| |     | |
| . ` | / _ \/ __|| __|    | | `--. \| |    | |     | |
| |\  ||  __/\__ \| |_ /\__/ //\__/ /| \__/\| |_____| |_
\_| \_/ \___||___/ \__|\____/ \____/  \____/\_____/\___/


[System Information]
OS Version     : macOS 23.2.0
NodeJS Version : v21.2.0
YARN Version    : 1.22.21 

[Nest CLI]
Nest CLI Version : 10.3.0 

[Nest Platform Information]
platform-express version : 10.3.0
schematics version       : 10.1.0
graphql version          : 12.0.11
typeorm version          : 10.0.1
testing version          : 10.3.0
apollo version           : 12.0.11
common version           : 10.3.0
config version           : 3.1.1
core version             : 10.3.0
jwt version              : 10.2.0
cli version              : 10.3.0

[Warnings]
The following packages are not in the same minor version
This could lead to runtime errors
* Under version 10.3
- @nestjs/platform-express 10.3.0
- @nestjs/common 10.3.0
- @nestjs/core 10.3.0
* Under version 10.1
- @nestjs/schematics 10.1.0
pseudo finch
#

That all looks good.
Could you double-check that with

  async login(@Args('input') input: LoginInputDTO): Promise<LoginResponseDTO> {

you import Args from @nestjs/graphql?

stable linden
#

Just tried again. input is still coming back undefined. It's so bizarre. I've created NestJS applications before using this auth strategy and never encountered this

pseudo finch
#

Could you try with this in your main.ts?

import { NestFactory } from "@nestjs/core";
import { Module } from "@nestjs/common";
import { ApolloDriver, ApolloDriverConfig } from "@nestjs/apollo";
import {
  Args,
  Field,
  GraphQLModule,
  InputType,
  Mutation,
  ObjectType,
  Query,
  Resolver,
} from "@nestjs/graphql";

@InputType("LoginInput")
export class LoginInputDTO {
  @Field() email!: string;
  @Field(() => String) password!: string;
}

@ObjectType("LoginResponse")
export class LoginResponseDTO {
  @Field() accessToken!: string;
}

@Resolver()
export class AuthResolver {
  @Query(() => String)
  async hello(): Promise<string> {
    return "Hello World!";
  }

  @Mutation(() => LoginResponseDTO)
  async login(@Args("input") input: LoginInputDTO): Promise<LoginResponseDTO> {
    console.log(input);
    return { accessToken: input.email };
  }
}

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: true,
    }),
  ],
  providers: [AuthResolver],
})
class AppModule {}

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}

bootstrap().catch(console.error);
stable linden
pseudo finch
#

Possibly. I noticed you use import aliases (src/xyz) maybe that could be the issue. If you have a monorepo setup, there are often similar behaving issues. I don't have any specific tips what to check for neither of those, but I'd investigate towards that direction.

stable linden
#

Thanks for your help @pseudo finch ! In the end, I've isolated the issue to the fact that I'm using this decorator on my ID fields in my DTOs: https://tripss.github.io/nestjs-query/docs/graphql/dtos/#idfield

If I just use @Field instead of @IDField everything works fine. Such an odd bug...

The query-graphql package leverages most decorators from @nestjs/graphql and TypeGraphQL, with the exception of FilterableField.

pseudo finch
#

That is odd. Maybe duplicate @nestjs/graphql packages? yarn why @nestjs/graphql could confirm that.

stable linden
#

Doesn't seem to be...

✗ yarn why @nestjs/graphql
yarn why v1.22.21
[1/4] 🤔  Why do we have the module "@nestjs/graphql"...?
[2/4] 🚚  Initialising dependency graph...
[3/4] 🔍  Finding dependency...
[4/4] 🚡  Calculating file sizes...
=> Found "@nestjs/[email protected]"
info Has been hoisted to "@nestjs/graphql"
info This module exists because it's specified in "dependencies".
info Disk size without dependencies: "3.52MB"
info Disk size with unique dependencies: "12.94MB"
info Disk size with transitive dependencies: "14.37MB"
info Number of shared dependencies: 27
✨  Done in 0.20s.
pseudo finch
#

I'm out of ideas then, sorry. Could eventually be a different library (graphql? nestjs/common or core?). I'd try submitting an issue to nestjs-query, maybe they're aware of that and have a fix.