Skip to content

@FieldResolver not... working? #1006

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
chiefGui opened this issue Sep 1, 2021 · 8 comments
Closed

@FieldResolver not... working? #1006

chiefGui opened this issue Sep 1, 2021 · 8 comments
Labels
Question ❔ Not future request, proposal or bug issue Solved ✔️ The issue has been solved

Comments

@chiefGui
Copy link

chiefGui commented Sep 1, 2021

Describe the Bug

  • I have a type, Todo, with a @Field() called text
  • I have a resolver, TodoResolver, which has a @FieldResolver() that is never called.

To Reproduce

// todo.schema.ts

@ObjectType()
export class Todo {
  @Field()
  _id: string

  @Field()
  text: string
}
// todo.resolver.ts

@Resolver(Todo)
export class TodoResolver implements ResolverInterface<Todo> {
  @Query((returns) => [Todo])
  async todos(): Promise<Todo[]> {
    return await [{ _id: Math.random().toString(), text: "hi!" }]
  }

  @FieldResolver((type) => Number)
  async text(@Root() todo: Todo): Promise<string> {
    console.log(todo) // never logs

    return await "hello world"
  }
}

And the query is:

query todos {
  todos {
    _id
    text
  }
}

FWIW, the tsconfig.json file is this:

{
  "compilerOptions": {
    "baseUrl": ".",
    "target": "esnext",
    "lib": ["dom", "dom.iterable", "esnext", "esnext.asynciterable"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

Expected Behavior
I'd like to see text as hello world when querying todos; I'm currently seeing hi!.

Logs
There are no errors.

Environment:

  • OS: macOS Big Sur 11.5.2
  • Node: v15.14.0
  • Package version: ^1.1.1
  • TypeScript version: ^4.4.2
  • I'm running the code above in a serverless environment; next.js, more precisely.

Additional Context
From all the examples I've seen/read related to type-graphql, the code above seems to be correct. This leads me to believe the problem is elsewhere—turns out I have no clue what this "elsewhere" could be.

That said, do you have any ideas on how/where should I be looking to find the culprit for the field resolver not be working? Or rather am I misinterpreting how field resolvers are supposed to work?

Thanks in advance,
Gui.

@chiefGui
Copy link
Author

chiefGui commented Sep 1, 2021

I just created a vanilla project, very minimal & simple, and the issue is still there. Click here to go to the repo or:

$ git clone [email protected]:chiefGui/typegraphql-test.git && cd typegraphql-test && yarn && yarn dev

Here's the query, once again:

query todos {
  todos {
    _id
    text
  }
}

FWIW, the only relevant folder is /pages/api.


Now I wonder:

@chiefGui
Copy link
Author

chiefGui commented Sep 1, 2021

OK, just tested the same implementation using express and apollo-server-express instead of nextjs + micro (stateful server vs. serverless functions) and the exact same code worked as expected perfectly. Yet, I still don't know if this is micro, or nextjs or even that FieldResolvers are not supposed to work with serverless functions.

By the way, I've already done this: #96 (comment). I know the problems are slightly different, but just as a safety measure, and as I was expecting, still didn't have success.

I wonder, does @FieldResolver() have any kind of persistence?

@MichalLytek
Copy link
Owner

You can call your queries by code, like:
https://github.com/MichalLytek/type-graphql/blob/master/tests/functional/simple-resolvers.ts#L75-L83

TypeGraphQL builds GraphQLSchema object, so if it works via the way mentioned above, it's not TypeGraphQL's fault.

With next or serverless you need to be aware of minifying the bundle which causes issues.

@MichalLytek MichalLytek added Need More Info 🤷‍♂️ Further information is requested Question ❔ Not future request, proposal or bug issue labels Sep 2, 2021
@MichalLytek
Copy link
Owner

Closing for a housekeeping purposes 🔒

@MichalLytek MichalLytek added Solved ✔️ The issue has been solved and removed Need More Info 🤷‍♂️ Further information is requested labels Sep 15, 2021
@mrkirchner
Copy link

@MichalLytek sorry to comment on a closed issue but can you provide a bit more clarification on what you mean?

When i use nextjs and do graphql via sdl, apollo-server-micro, and micro, things work fine, but when i use typegraphql only queries and mutations work, Field Resolvers are never called.

Is there something in babel or webpack that might cause this issue? Here is a repo with both running

https://github.com/mrkirchner/NextJS-Typegraphql

Thanks for any help.

@dgurns
Copy link

dgurns commented Nov 27, 2021

@MichalLytek would love to hear more about "With next or serverless you need to be aware of minifying the bundle which causes issues."

I've been using field resolvers with no problem when compiling with Webpack and ts-loader, but when I switched to swc-loader I started seeing problems.

Everything else seems to be working fine.

Thanks for a great project btw.

.swcrc:

{
	"module": {
		"type": "commonjs"
	},
	"jsc": {
		"baseUrl": ".",
		"parser": {
			"syntax": "typescript",
			"decorators": true
		},
		"target": "es2018",
		"transform": {
			"legacyDecorator": true,
			"decoratorMetadata": true
		}
	}
}

@dgurns
Copy link

dgurns commented Nov 28, 2021

An update for anyone who is running into this problem where a FieldResolver isn't being run: It was luckily a really stupid error on my part.

I had a redundant Field() and FieldResolver() defined like this:

@ObjectType()
export class MyClass {
  Field(() => String)   <-- Just needed to remove this line!
  myField: string;
}

@Resolver()
export class MyClassResolver {
  @FieldResolver(() => String)
  myField(@Root() myClass: MyClass) {
    return 'sample string';
  }
}

And after that everything works great, whether compiling with swc or even using swc-loader with Webpack.

@robations
Copy link

I was also wrestling with this issue. If I remove the @Field decorator as @dgurns suggested I just get an error that schema metadata is missing.

In my case I solved it by combining separate resolver classes for the FieldResolver/Resolver (existing code was a bit weird but seemed to work):

From

    @Resolver(() => Prediction)
    class PredictionResolver {
        @FieldResolver()
        async geometry(@Root() p: Prediction): Promise<any> {
            return detailsRequest({
                placeId: p.place_id,
                fields: ["geometry"],
            }).then((res) => (res && res.geometry ? res.geometry : null));
        }
    }

    @Resolver()
    class AutocompleteResolver {
        @Query(() => [Prediction], { nullable: true })
        async autocomplete(@Arg("input") input: string): Promise<Prediction> {
            return autocompleteRequest({
                input,
            });
        }
    }

To

    @Resolver(() => Prediction)
    class AutocompleteResolver {
        @Authorized(["ROLE_USER"])
        @Query(() => [Prediction], { nullable: true })
        async autocomplete(@Arg("input") input: string): Promise<Prediction> {
            return autocompleteRequest({
                input,
                types,
                radius,
                language,
                offset,
                strictbounds,
            });
        }

        @FieldResolver()
        async geometry(@Root() p: Prediction): Promise<Geometry | null> {
            return detailsRequest({
                placeId: p.place_id,
                fields: ["geometry"],
            }).then((res) => (res && res.geometry ? res.geometry : null));
        }
    }

Hope this helps someone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question ❔ Not future request, proposal or bug issue Solved ✔️ The issue has been solved
Projects
None yet
Development

No branches or pull requests

5 participants