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

Problem accessing properties in class extending IEnumerable #694

Open
CheloXL opened this issue Aug 27, 2024 · 6 comments
Open

Problem accessing properties in class extending IEnumerable #694

CheloXL opened this issue Aug 27, 2024 · 6 comments

Comments

@CheloXL
Copy link

CheloXL commented Aug 27, 2024

I have the following code:

class Permit {
    public VehicleHistory Vehicles {get...}
}

class VehicleHistory : IEnumerable<PermitVehicle> {
    public IEnumerable<Vehicle> Approved {get...}
}

record PermitVehicle {
    public required Vehicle Value { get; init; }
    public  required ApprovalStatus Status { get; init; }
}

And now, passing an instance of Permit to a template like {% for vehicle in Permit.Vehicles.Approved %} {{ vehicle.Value.Plate }} {% endfor %} renders nothing. It seems that fluid detects that Vehicles is an IEnumerable and stop trying to get the next property. Of course iterating over Vehicles works, but that makes me replicate the same code I have in Approved into the template.

Not sure if this is by design, or a problem in the template system.

@sebastienros
Copy link
Owner

stop trying to get the next property

That is a possibility if this property is converted to an ArrayValue. In that case it will only try to access internal properties (size, ...). And if you try using the indexer then it will only accept numbers.

In this case you would probably need a mix of ArrayValue and ObjectValue. Or just have a custom class inheriting from ObjectValueBase which would implement Enumerate(TemplateContext) to return the list of values too when used as an array. And to use it just register VehicleHistory to be converted to YourCustomEnmerableValue(theVehicleHistory)

Also, why do you need to use Value in vehicle.Value.Plate?

@CheloXL
Copy link
Author

CheloXL commented Aug 28, 2024

Mmmm.. I don't know how the properties are converted... I'm passing an object with the property Permit filled in with an instance of a Permit to the RenderAsync method. No object in my code extends anything like ArrayValue nor ObjectValue.

Regarding your second question: My bad. I copied the code I used in the meanwhile, that iterates over Vehicles (and I'm filtering vehicles with an if). It should be vehicle.Plate in the example above.

@sebastienros
Copy link
Owner

No object in my code extends anything like ArrayValue nor ObjectValue.

Which is normal. This is what Fluid uses internally. I was just suggesting you create a similar class by inheriting ObjectValueBase to fix your problem quickly, I would need more time to think about the best solution that would make it work in all cases otherwise.

@CheloXL
Copy link
Author

CheloXL commented Aug 28, 2024

Ahhh, perfect. Yes, as I said, I already fixed that by iterating over the Vehicles and manually filtering what I need. I would see if I can work around using what you suggested and see what happens. Thank you!

@sebastienros
Copy link
Owner

manually filtering

Just in case you don't know, there is a filter for that: https://shopify.github.io/liquid/filters/where/

@sebastienros
Copy link
Owner

Even though there is a mitigation I am keeping this issue open as I might want to revisit the distinction between ArrayValue and ObjectValue to allow for this scenario.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants