graphql-platform icon indicating copy to clipboard operation
graphql-platform copied to clipboard

Filtering on properties that are extended via extended types don't seem to work

Open Archomeda opened this issue 3 years ago • 7 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the bug

When using an IList<T> as return type in a query, where T is a defined type, and has a property that is extended via a class that has the ExtendObjectTypeAttribute defined on it, filtering on that property doesn't seem to work. It seems that it filters on the default value of that property, instead of filtering on the actual value that gets populated via the extension.

I'm expecting this to work like every other property that is initially set in the data loader.

Steps to reproduce

Sample as close as possible to my code that explains the process:

// Type
public class MyEnum
{
    DefaultValue = 0,
    Value1,
    Value2,
}

public class MyResultType
{
    public string Id { get; set; }
    public MyEnum SomeEnumValue { get; set; }
}

// Query
public class MyQuery
{
    [UseFiltering]
    public async Task<IList<MyResultType>> GetResultAsync(MyDataLoader dataLoader)
    {
        // Simplified for brevity (this dataloader doesn't load the value of SomeEnumValue in the object)
        return await dataLoader.LoadAsync(string.Empty);
    }
}

// Extension
[ExtendObjectType(typeof(MyResultType))]
public class MyResultTypeExtensions
{
    public async Task<MyEnum> GetSomeEnumValueAsync([Parent] MyResultType parent, MyInnerDataLoader dataLoader)
    {
        // Simplified for brevity (this dataloader loads the value of SomeEnumValue)
        return await dataLoader.LoadAsync(parent.Id);
    }
}

// Omitted dataloaders for brevity

Query:

{
    result(where: { someEnumValue: { eq: VALUE_1 } })
    {
        id
        someEnumValue
    }
}

When running this query, you'll never get a result, even though the result may contain an item that has the enum value Value1. Because the enum value is set to default when returning from the GetResultAsync method, you'll only get results from this query when you filter on { eq: DEFAULT_VALUE }.

Relevant log output

No response

Additional Context?

No response

Product

Hot Chocolate

Version

12.13.2

Archomeda avatar Sep 09 '22 10:09 Archomeda

Someone may correct me, but I think the issue is not the extension, but that the extension is a Method instead of a property. Currently filters only work on properties in order to make filtering also work with databases for instance. Interesting thing is, that with the type extension you seem to be able to get the filter input generated. If it was already a method in first place, someEnumValue would be omitted from the input.

tsinghammer avatar Sep 09 '22 11:09 tsinghammer

Hmm... interesting. Yeah the property is defined in the type itself as well as part of the extension as a method. If what you're saying is correct, is there anything I can do on my part to make it work?

Archomeda avatar Sep 09 '22 11:09 Archomeda

The way I solved it in one application is that I set the SomeEnumValue property whenever new data comes in and store the whole object together with it n memory or database. This way I don’t need the additional resolver. But that may not be an option in your case. It was a trade of for me between the convenience of auto generated filters and having to keep the dependent data up to date or using resolvers but having to write my own filters.

tsinghammer avatar Sep 09 '22 11:09 tsinghammer

I see. I'm probably able to put it in the same data loader (in this sample that would be MyDataLoader) instead of having a separate one via the extension.

Archomeda avatar Sep 09 '22 11:09 Archomeda

HI all. Is it already possible to filter on extended types?

neklahcs avatar Aug 03 '23 11:08 neklahcs

I'm trying to filter on extended types:

public class Query	
{
	[UsePaging]
	[UseProjection]
	[UseFiltering]
	[UseSorting]
	[GraphQLName("datas")]
	public IEnumerable<DataDto> GetAllData(Service service)
	{
		return Mapper.ProjectTo<DataDto>(service.GetAllData());
	}
}


[ExtendObjectType(typeof(DataDto))]
public class Extension
{
	[GraphQLName("component")]
	public Component GetCompnoent(Service service, [Parent]DataDto parentDto)
	{
		return service.OtherComponent.TryGetValue(parentDto.componentId, out var result) ? result : null;
	}
}


query {
  data(where: {component: {data: {eq: "something"}}}) {
    nodes {
      componentId
      component {
		data
      }
    }
  }
}

I can't filter on the data field of my component.

Nickert1337 avatar Aug 03 '23 13:08 Nickert1337