Type-graphql: Error when using GraphQLJSON

Created on 31 Oct 2018  路  17Comments  路  Source: MichalLytek/type-graphql

The latest version (0.15.0) seems to have issues with custom scalars such as the JSON type provided by the GraphQLJSON package (graphql-type-json).

Here is a basic example of what I'd like to do:

import { ObjectType, Field } from "type-graphql";
import GraphQLJSON = require("graphql-type-json");

@ObjectType()
export default class MyData {

    @Field(type => GraphQLJSON)
    public jsonData: any;
}

This results in the following error: "Error: Cannot determine GraphQL input type for jsonData".

When I go back to the previous version (0.14.0) and GraphQL version 0.13.2, the error disappears and my code works again.

Environment:

  • OS: Mac, Windows
  • Node: 10.12.0
  • Package version: 0.15.0
  • TypeScript version: 3.1.4
Question Solved

Most helpful comment

@darkmantle

Setting:

  "allowSyntheticDefaultImports": true,
  "esModuleInterop": true,

Means you should use default import:

import GraphQLJSON from "graphql-type-json";

All 17 comments

According to the code:
https://github.com/taion/graphql-type-json/blob/5790abc351b3007dc9dc98ccf35e9ea72ed7ba91/src/index.js#L37

You should do:
import GraphQLJSON = require("graphql-type-json").default;

But as I've tried in reproduction repo:
https://gitlab.com/esindger/tgql-scalar-example

You should do:
import * as GraphQLJSON from "graphql-type-json";
instead of:
import GraphQLJSON from "graphql-type-json";

Then it works 馃槂
code_2018-10-31_18-35-48

Thanks for your response! After making this change it works :).

I'm running into this issue myself, and the suggested fix doesn't seem to help.

I traced it down and it seems like this check is failing:

https://github.com/19majkel94/type-graphql/blob/63d4858f882625ef9bebcf2ce5fa0150662a93e6/src/helpers/types.ts#L18

It appears that there's two different copies of GraphQLScalarType being loaded - one by the GraphQLJSON lib and one by TypeGraphQL. I can probably figure out a workaround for this particular case, but long term it seems like it might be better to avoid relying on instanceof checks like that unless we can be certain the object being tested was created internally in TypeGraphQL (and therefore will have the correct prototype chain).

In another thread one idea mentioned was to simply export GraphQLScalarType from TypeGraphQL so consuming apps could use it to properly construct an instance with the necessary prototype chain, but I don't think that would work here either, since the GraphQLJSON library is the one using GraphQLScalarType.

@davewasmer
That's the main reason why I decided to switch to peer-dependency. This issue should be fixed in next release. For now you can try npm dedupe.

Have tried npm dedupe but still getting this error. Any ideas? It's completely broken my API now.

That fixed some of it, but not completely. Not sure if it is the same problem, but I get the same error on:

@Mutation(returns => ApiError)
    async recordConsent(@Arg("consents", type => GraphQLJSON) consents: UserConsent[]) {
        const body = await FetchConfig.fetch("user-record-consent", { consents });
        return body;
    }

@darkmantle Please create a repository with reproducible code example.

@darkmantle

Setting:

  "allowSyntheticDefaultImports": true,
  "esModuleInterop": true,

Means you should use default import:

import GraphQLJSON from "graphql-type-json";

Thank you! I actually changed it everywhere but that one place. Rookie error.

The type instanceof GraphQLScalarType checks also seems to cause issues if you yarn link into another project that has a different version of graphql installed. Would it make sense to use type.constructor.name checks here to guard against this?

No, you need to have only one version of graphql-js in your project, otherwise you will have the "another realm" error.

I have the same problem with this library:
https://www.npmjs.com/package/graphql-custom-types

The thing that works for me to use "graphql-type-json" package.

   import { GraphQLJSONObject } from 'graphql-type-json';
   import { Field, InputType, Int, ObjectType } from 'type-graphql';
   import { Entity, ManyToOne, JoinTable, Column } from 'typeorm';
 ...other libraries
  @ObjectType('DemoModelType') 
  @InputType('DemoModelInput')
  @Entity()
  export class DemoModel {
... columns before it
    @Field(() => GraphQLJSONObject || null, { nullable: true })
    @prop({ unique: false, required: false })
    @Column()
    public myKey!: object | null;
}

NOTE: This can also happen if you are using two different versions of graphql.

Why? If you trace the error you find that it checks if the type is a scalar by checking instanceof graphql.GraphQLScalarType. This will fail if the scalar was not created using the same graphql instance.

_/xxx/node_modules/.pnpm/[email protected]/node_modules/type-graphql/dist/helpers/types.js_

function convertTypeIfScalar(type) {
    if (type instanceof graphql_1.GraphQLScalarType) {
        return type;
    }
    const scalarMap = build_context_1.BuildContext.scalarsMaps.find(it => it.type === type);
    if (scalarMap) {
        return scalarMap.scalar;
    }
    switch (type) {
        case String:
            return graphql_1.GraphQLString;
        case Boolean:
            return graphql_1.GraphQLBoolean;
        case Number:
            return graphql_1.GraphQLFloat;
        case Date:
            return build_context_1.BuildContext.dateScalarMode === "isoDate" ? isodate_1.GraphQLISODateTime : timestamp_1.GraphQLTimestamp;
        default:
            return undefined;
    }
}

Would be nice if type-graphql could provide some kind of check for us...

Would be nice if type-graphql could provide some kind of check for us...

Do you know how type-graphql could check that? 馃

Was this page helpful?
0 / 5 - 0 ratings

Related issues

itsgracian picture itsgracian  路  3Comments

MichalLytek picture MichalLytek  路  4Comments

robertchung97 picture robertchung97  路  3Comments

maplesteve picture maplesteve  路  3Comments

tafelito picture tafelito  路  3Comments