[ ] Regression [*] Bug report [ ] Feature request [ ] Documentation issue or request [ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Hello,
I'm using the graphql example( in the example directory of nest) with the Cat CRUD and i try to use a union type and interface but i didn't find a way to do it.
When i try to request my data with a fragment, i have the following error :
"Abstract type MutationResult must resolve to an Object type at runtime for field Mutation.createCat with value \"[object Object]\", received \"undefined\". Either the MutationResult type should provide a \"resolveType\" function or each possible types should provide an \"isTypeOf\" function."
There is nothing in the doc explaining how to use union / interface, and there is nothing in the graphql example.
In the apollo documentation, the type resolver ( here "Cat" Resolver") should implement a __resolveType function. I tried to set this function in the @Resolver('Cat') class CatsResolvers
but it's not working.
I tried to add it on the cat resolvers class
The request should return either a Cat item or GraphQLErrorItem from my schema definition.
export interface GraphQLError {
readonly message: string;
readonly errorCode: number;
readonly type: string;
}
type GraphQLError {
message: String
errorCode: Int
type: String
}
union MutationResult = Cat | GraphQLError
- createCat(name: String, age: Int): MutationResult
__resolveType(obj, context, info): string{
return obj.errorCode ? 'GraphQLError' : 'Cat';
}
Nest version: 4.5.10 (core)
For Tooling issues:
- Node version: 9.4
- Platform: Mac
Others:
@fosk06 For error handling you are not required to do something like unions. In your app.module or graphql.module you can simply just do this
.apply(
graphqlExpress(async req => ({
schema: schema
rootValue: req,
context: req,
formatError: (error: GraphQLError) => {
return error.originalError instanceof BaseException ? error.originalError.serialize() : error;
}
}))
)
@kamilmysliwiec But for _real_ unions and interfaces it is not quite clear how to resolve those.
# Schema
union SearchResult = Human | Droid | Starship
# Query
{
search(text: "an") {
... on Human {
name
height
}
... on Droid {
name
primaryFunction
}
... on Starship {
name
length
}
}
}
A NestJS way could look somethin like
@ResolveType('SearchResult')
async resolveType(obj) {
if(obj.height){
return 'Human';
}
if(obj.length){
return 'Starship';
}
}
What do you think?
This is something I am struggling with as well.
Same here.
There is workaround though - add it manually when creating schema (ugly one)
const typeDefs = this.graphQLFactory.mergeTypesByPaths('./**/*.graphqls');
const resolvers = {
LoginResponse: {
__resolveType(obj, context, info) {
if (obj.error) {
return 'LoginFailure';
}
return 'LoginSuccess';
}
}
};
const schema = this.graphQLFactory.createSchema({ typeDefs, resolvers });
you can do this by defining it as a normal type
@Resolver('LoginResponse')
export class LoginResponseResolver {
@ResolveProperty('__resolveType')
__resolveType(obj) {
if (obj.error) {
return 'LoginFailure';
}
return 'LoginSuccess';
}
}
Yay, thanks
Actually, this should be enough (you can omit __resolveType inside parenthesis):
@Resolver('LoginResponse')
export class LoginResponseResolver {
@ResolveProperty()
__resolveType(obj) {
if (obj.error) {
return 'LoginFailure';
}
return 'LoginSuccess';
}
}
Hey guys @kamilmysliwiec @ph55 @obedm503
I faced a similar problem but a bit different:
Let's say we have the following schema:
type Component {
id: ID!
type: ComponentTypes!
order: Int!
properties: ComponentProps!
}
enum ComponentTypes {
TEXT
BUTTON
}
union ComponentProps = TextComponentProps | ButtonComponentProps
type TextComponentProps {
text: String
}
type ButtonComponentProps {
color: String
}
How to resolve union ComponentProps as it depend on Component.type value?
Hey @kamilmysliwiec @ph55 @obedm503
Can you help with some advice on this :arrow_up: please
Still unclear on how this is meant to work. @kamilmysliwiec, would you mind clarifying this use case? I have a resolver the way you have specified and yet still receive the warning.
@igat64 it's not possible since TextComponentProps or ButtonComponentProps doesn't have a way to relate back to the component type. the code would just have to know the relationships
Thank you for the answer @obedm503
Hey, great solution but i think it could be better, just using a ResolveProperty function instead using a Resolver, because it needs the creation a new class and file for each union type, it creates multiples scopes of one model that should be summed up in one general resolver file. What do you guys think about it?
@yassern What is your solution proposal?
Anyone help me to demo union with nestjs + graphql ?
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
Hey guys @kamilmysliwiec @ph55 @obedm503
I faced a similar problem but a bit different:
Let's say we have the following schema:
How to resolve union
ComponentPropsas it depend onComponent.typevalue?