Reputation: 5459
I have a simple enum that I am trying to include in my GraphQL type and am receiving the following error:
The GraphQL type for Field: 'Category' on parent type: 'NewsItemType' could not be derived implicitly.
------------------The GraphQL type for Field: 'Category' on parent type: 'NewsItemType' could not be derived implicitly.
---------------The type: NewsType cannot be coerced effectively to a GraphQL type Parameter name: type
my simple enum looks like:
public enum NewsType
{
General = 0,
Business = 1,
Entertainment = 2,
Sports = 3,
Technology = 4
}
The GraphQL ObjectGraphType
that it is included in:
public class NewsItemType : ObjectGraphType<NewsItemViewModel>
{
public NewsItemType()
{
Field(x => x.Id).Description("Id of a news item.");
Field(x => x.Title).Description("Title of a new item.");
Field(x => x.Description).Description("Description of a news item.");
Field(x => x.Author).Description("Author of a news item.");
Field(x => x.Url).Description("URI location of the news item");
Field(x => x.ImageUrl).Description("URI location of the image for the news item");
Field(x => x.PublishDate).Description("Date the news item was published");
Field(x => x.Category).Description("Category of the news item.");
}
}
and finally, the view model that the GraphQL type is based on:
public class NewsItemViewModel : ViewModelBase
{
public string Title { get; set; }
public string Author { get; set; }
public string Description { get; set; }
public string Url { get; set; }
public string ImageUrl { get; set; }
public DateTime PublishDate { get; set; }
public NewsType Category { get; set; }
}
What am I doing wrong here and how can I overcome it?
EDIT: my query contains the following:
Field<ListGraphType<NewsItemType>>(
name: "newsItems",
arguments: new QueryArguments(
new QueryArgument<IntGraphType>() { Name = "count" },
new QueryArgument<IntGraphType>() { Name = "category" }),
resolve: context =>
{
var count = context.GetArgument<int?>("count");
var category = context.GetArgument<int>("category");
var newsType = (NewsType)category;
if (count.HasValue)
{
return newsItemService.GetMostRecent(newsType, count.Value);
}
else
{
return newsItemService.GetMostRecent(newsType);
}
}
)
Upvotes: 5
Views: 4733
Reputation: 11474
I had a very hard time getting this to work as well. Official documentation definitely seems to be lacking in this regard. The way I got it to work was based on something I found in this article.
For your scenario, you would create a 'GraphType' class for your enum as follows:
public class NewsEnumType : EnumerationGraphType<NewsType>
{
}
Then update your field to:
Field<NewsEnumType>(nameof(NewsItemViewModel.Category)).Description("Category of the news item.");
One other thing to mention that I ran into with EnumTypes that I wasn't expecting. If you are using an enum as a parameter, do what you did above where you ingest it as an IntGraphType
and then cast it to your enum type (NewsType)category
Field<ListGraphType<NewsItemType>>(
name: "newsItems",
arguments: new QueryArguments(
new QueryArgument<IntGraphType>() { Name = "count" },
new QueryArgument<IntGraphType>() { Name = "category" }),
resolve: context =>
{
var count = context.GetArgument<int?>("count");
var category = context.GetArgument<int>("category");
var newsType = (NewsType)category;
if (count.HasValue)
{
return newsItemService.GetMostRecent(newsType, count.Value);
}
else
{
return newsItemService.GetMostRecent(newsType);
}
}
)
My enum was part of a complex object that I was passing as a parameter, more like new QueryArgument<NewsItemType>() { Name = "newsItem" },
If you are going to do that, then the category
property on the object passed to the server needs to be a string. So, if the category you are passing back to the server is Business = 1
, then you would need to pass category: 'Business'
and NOT category: 1
.
Upvotes: 7
Reputation: 71
Here's a quick way to do this for your case. Basically you don't use the default lambda expression Field
. Instead actually write out a resolver yourself and convert the enum to the proper type. This is helping GraphQL to convert the type properly into the type you want to return.
Field<IntGraphType>("category", resolve: context => (int)context.Source.Category);
If your enum was a string, you could do the same for that as well.
Field<StringGraphType>("category", resolve: context => context.Source.Category.ToString());
There is another, more verbose way, shared in this answer where you inherit from the EnumerationGraphType<T>
first and then do the same custom resolver as above.
https://stackoverflow.com/a/56051133/11842628
Upvotes: 6