Type-graphql: Expect value of type error using ObjectType inheritance

Created on 5 May 2018  路  7Comments  路  Source: MichalLytek/type-graphql

I couldn't get inheritance to work with ObjectType():

````
@ObjectType()
export class CursorPagination{
@Field(type=>String,{nullable:true})
maxId:string;
}

@ObjectType()
class ItemList extends CursorPagination{
@Field(type=>[Item])
list:Item[];

@Field(type=>ID)
id:string;

}
There's no error when the server starts, but it will throw this error when fetching the list data:
GraphQLError: Expected value of type "ItemList" but got: [object Object].
````

Not using the inheritance make things work again.

Question Solved

Most helpful comment

I would even recommend creating your own helper function:

function toObjectType<T>(Type: new (...args: any[]) => T, object: T) {
    return Object.assign(new Type(), object);
}

Then use it:

@Query(return => MyInterface) {
  return toObjectType(MyType, {
    whoLetTheDogsOut: "WHO? WHO? WHO? WHO?",
  });
}

class-transformer is a bit heavy and slow, so should be used only in case you have a big an complicated class type with a lot of nested types and arrays, mostly in case of serialization-deserialization.
TypeGraphQL only need the instance of to work, so only the object prototype is important. The rest might be like in a plain object.

All 7 comments

Please crate a repository with minimal amount of code to reproduce the issue.
I'm not able to figure out what's wrong from the object class and [object Object] error.

I'm debugging the invalidReturnTypeError. The [object Object] is actually the list result : {list:[{xxx}], id:"123"}. I'll set up an example later.

Maybe your query return type is an interface/union and you forget to return instance of the object type class? 馃槙

Oh my....
I just returned plain objects in these list queries with pagination data. I've been doing it this way in all of the resolvers.

That error happened only when I started using inheritance.

Now I have to rewrite all the code from

` @Query(returnType=>ItemList){ getList(){ return { list:[{xxx:1}], id:1 } } }

to

@Query(returnType=>ItemList) getList(){ let itemList = new ItemList(); itemList.list = []; itemList.list = "33" return itemList; } }

https://19majkel94.github.io/type-graphql/docs/interfaces-and-inheritance.html

Be aware that when your object type is implementing GraphQL interface type, you have to return an instance of the type class in your resolvers. Otherwise, graphql-js will not be able to detect the underlying GraphQL type correctly.

TypeGraphQL checks the underlying object type by using instance of. Without this, graphql-js demands creating isTypeOf function for each ObjectType, so you would have to create functions like return obj && typeof obj.id === "string" && Array.isArray(obj.list ) ... to define what is the type of plain object that you returns.

Is it best to implement isTypeOf or use class-transformer to initialise an instance of a object type class?

https://github.com/typestack/class-transformer

I would even recommend creating your own helper function:

function toObjectType<T>(Type: new (...args: any[]) => T, object: T) {
    return Object.assign(new Type(), object);
}

Then use it:

@Query(return => MyInterface) {
  return toObjectType(MyType, {
    whoLetTheDogsOut: "WHO? WHO? WHO? WHO?",
  });
}

class-transformer is a bit heavy and slow, so should be used only in case you have a big an complicated class type with a lot of nested types and arrays, mostly in case of serialization-deserialization.
TypeGraphQL only need the instance of to work, so only the object prototype is important. The rest might be like in a plain object.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MichalLytek picture MichalLytek  路  3Comments

reilem picture reilem  路  3Comments

Janushan picture Janushan  路  3Comments

glentakahashi picture glentakahashi  路  3Comments

MichalLytek picture MichalLytek  路  4Comments