Skip to content
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

Expect value of type error using ObjectType inheritance #73

Closed
laukaichung opened this issue May 5, 2018 · 7 comments
Closed

Expect value of type error using ObjectType inheritance #73

laukaichung opened this issue May 5, 2018 · 7 comments
Labels
Question ❔ Not future request, proposal or bug issue Solved ✔️ The issue has been solved

Comments

@laukaichung
Copy link

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.

@MichalLytek
Copy link
Owner

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.

@MichalLytek MichalLytek added the Need More Info 🤷‍♂️ Further information is requested label May 5, 2018
@laukaichung
Copy link
Author

laukaichung commented May 5, 2018

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

@MichalLytek
Copy link
Owner

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

@laukaichung
Copy link
Author

laukaichung commented May 5, 2018

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;
    }
}
````

@MichalLytek
Copy link
Owner

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.

@MichalLytek MichalLytek added Question ❔ Not future request, proposal or bug issue and removed Need More Info 🤷‍♂️ Further information is requested labels May 5, 2018
@ashleyw
Copy link

ashleyw commented May 5, 2018

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

@MichalLytek
Copy link
Owner

MichalLytek commented May 5, 2018

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.

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

3 participants