Type-graphql: Adding any @FieldResolver crashes build

Created on 10 May 2020  路  10Comments  路  Source: MichalLytek/type-graphql

Describe the Bug
Adding the @ Field decorator to a model does nothing and adding the @ FieldResolver decorator to a Resolver crashes the build process. Either this is a bug or I have done something wrong.

Adding any @ FieldResolver decorator will cause this, even one that simply returns a preset string.

To Reproduce

model

@ObjectType("Album")
export class AlbumModel {
  @Field(() => ID)
  id: string;

  @Field()
  title: string;

[1]
  // @Field(() => [SocialLinkModel])
  // social: SocialLinkModel[];

[2]
 // @Field(() => [SocialLinkModel])
 // social(@Root() album: AlbumEntity) {
 //   return album.social?.links ?? [];
 // }

}

@ObjectType("SocialLink")
export class SocialLinkModel {
  @Field(() => ID)
  id: string;

  @Field()
  site: string;

  @Field()
  url: string;
}

[3] In addition, doing this in place of [2] causes the same issue

 @Field(() => [SocialLinkModel])
  social(@Root() album: AlbumEntity): SocialLinkModel[] {
    return [{ id: "2", url: "foo", site: 1 }];
  }

resolvers

@Resolver((_of) => AlbumModel)
export class AlbumResolver {

[1]
  @FieldResolver(() => [SocialLinkModel])
  async social(@Root() album: AlbumEntity) {
    return album.social?.links ?? [];
  }

  @Query(() => [AlbumModel])
  albums() {
    return AlbumEntity.find({ relations : ["social","social.links"] });
  }
}

Expected Behavior
or
Logs
[1]

(node:76612) UnhandledPromiseRejectionWarning: Error: Unable to find type metadata for input type or object type named ''
    at /Users/me/documents/api/node_modules/type-graphql/dist/metadata/metadata-storage.js:183:27
    at Array.forEach (<anonymous>)
    at MetadataStorage.buildFieldResolverMetadata (/Users/me/documents/api/node_modules/type-graphql/dist/metadata/metadata-storage.js:167:21)
    at MetadataStorage.build (/Users/me/documents/api/node_modules/type-graphql/dist/metadata/metadata-storage.js:100:14)
    at Function.generateFromMetadataSync (/Users/me/documents/api/node_modules/type-graphql/dist/schema/schema-generator.js:27:51)
    at Function.generateFromMetadata (/Users/me/documents/api/node_modules/type-graphql/dist/schema/schema-generator.js:15:29)
    at Object.buildSchema (/Users/me/documents/api/node_modules/type-graphql/dist/utils/buildSchema.js:9:61)

[2] and [3]
image

Environment (please complete the following information):

  • OS: [macOS 10.15.4]
  • Node (v12.16.3)
  • Package version [^1.0.0-rc.1] and [0.18.0-beta.17]
  • TypeScript version [^3.8.3]
  • TypeORM version [^0.2.24]

Additional Context
Thanks for taking the time to look at this. Love this framework, would love to figure this out so I can continue using it!

Question Solved

Most helpful comment

I bet you have target: es5 in your tsconfig.json file :stuck_out_tongue:
https://typegraphql.com/docs/installation.html#typescript-configuration

All 10 comments

even this causes the same error

  @FieldResolver(() => String)
  foo() {
    return "bar";
  }

(error)

UnhandledPromiseRejectionWarning: Error: Unable to find type metadata for input type or object type named ''

I followed the stack trace to metadata/metadata-storage.js and logged the def object:

{
  kind: 'external',
  methodName: 'foo',
  schemaName: 'foo',
  target: [Function: AlbumResolver],
  getType: [Function: getType],
  typeOptions: {},
  complexity: undefined,
  description: undefined,
  deprecationReason: undefined,
  resolverClassMetadata: {
    target: [Function: AlbumResolver],
    getObjectType: [Function],
    isAbstract: false
  },
  params: [],
  roles: undefined,
  middlewares: [],
  directives: [],
  extensions: {},
  getObjectType: [Function]
}

I bet you have target: es5 in your tsconfig.json file :stuck_out_tongue:
https://typegraphql.com/docs/installation.html#typescript-configuration

@MichalLytek it really be like that sometimes.

@jaminhaber I know, many people like to play with code and forgot to read the docs first, and I have to handle all that kind of issues 馃槙

Does changing to es2018 fixed your issue?

I changed to ES2020 and it works.

thanks

I hit the same issue even with target: es2018.
I have a similar set up as @jaminhaber, I logged out the def object:

{
  kind: 'external',
  methodName: 'user',
  schemaName: 'user',
  target: [Function: AdminManagerResolver],
  getType: [Function: getType],
  typeOptions: {},
  complexity: undefined,
  description: undefined,
  deprecationReason: undefined,
  resolverClassMetadata: {
    target: [Function: AdminManagerResolver],
    getObjectType: [Function (anonymous)],
    isAbstract: false
  },
  params: [
    {
      kind: 'root',
      target: [Function: AdminManagerResolver],
      methodName: 'user',
      index: 0,
      propertyName: undefined,
      getType: [Function: getType]
    }
  ],
  roles: undefined,
  middlewares: [],
  directives: [],
  extensions: {},
  getObjectType: [Function (anonymous)]
}

This is what my FieldResolver looks like:

@FieldResolver(() => User)
  public async user(@Root() manager: Manager): Promise<User> {
    return this.managerLoaders.user.load(manager.id);
  }

I made sure the tsconfig.json is correct based on the link provided above, any thoughts?

One thing to mention is that I'm able to run the code just fine with ts-node or ts-node-dev.

However, when I was trying to build the source and run it with node, I got the error.

Here's how I am building the source with tsc and babel:

tsc && babel ./src --out-dir ./build --extensions '.ts,.js'

Not sure if it's babel not respecting the emitDecoratorMetadata? here's my babel.config.js:

module.exports = function(api) {
  api.cache(true);

  const presets = [
    '@babel/env',
    '@babel/preset-typescript',
  ];
  const plugins = [
    [
      "module-resolver",
      {
        "root": [
          "."
        ],
        "alias": {
          "@common": "./src/common",
          "@services": "./src/services",
          "@entities": "./src/entities",
          "@interfaces": "./src/interfaces",
          "@repositories": "./src/repositories",
          "@db": "./src/db",
          "@graphql": "./src/graphql"
        },
        "extensions": [
          ".js",
          ".ts"
        ]
      }
    ],
    'babel-plugin-transform-typescript-metadata',
    [
      '@babel/plugin-proposal-decorators',
      {
        legacy: true
      }
    ],
    [
      '@babel/plugin-proposal-class-properties',
      {
        loose: true
      }
    ],
    '@babel/proposal-object-rest-spread',
  ];

  return {
    presets,
    plugins,
  };
}

Does anyone have solutions to this problem? I'm having the same problem.

I think the babel plugin does not support decorator metadata. You can check transpiled code.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

oliversalzburg picture oliversalzburg  路  3Comments

laukaichung picture laukaichung  路  3Comments

tongtwist picture tongtwist  路  3Comments

glentakahashi picture glentakahashi  路  3Comments

Janushan picture Janushan  路  3Comments