C
C#2y ago
oe

✅ Client needs filtering logic - what's the best way to implement?

I have two classes like so:
public class VirtualStore
{
public string StoreName { get; set; }

public List<VirtualProduct> Products { get; set; } = new();
}
public class VirtualStore
{
public string StoreName { get; set; }

public List<VirtualProduct> Products { get; set; } = new();
}
public class VirtualProduct
{
public string Image { get; set; }
public string StockNumber { get; set; }
public string Description { get; set; }
public string URL { get; set; }
public string Category { get; set; }
public string Price { get; set; }
public string Currency { get; set; }
}
public class VirtualProduct
{
public string Image { get; set; }
public string StockNumber { get; set; }
public string Description { get; set; }
public string URL { get; set; }
public string Category { get; set; }
public string Price { get; set; }
public string Currency { get; set; }
}
After my program runs, the List<VirtualProduct> Products variable is filled with objects and a JSON of it is returned to the client. I want my client who knows nothing about coding to be able to filter products by writing in some language or query what objects he wants to keep in that list, based on certain conditions, like: "CONTAINS toy", "EQUALS Best Toy In America", "NOT {{StoreName}}" Should I implement this logic on my own, or use some sort of existing query language that C# can interpret / solution for this? Thanks!
24 Replies
oe
oeOP2y ago
Think I might do something like this, anyone have any better advice?
using Jint;

var engine = new Engine()
.SetValue("products", Products);

var filteredProducts = engine.Execute("products.filter(p => p.Description.includes('toy') || p.URL === 'BestToyInAmerica.com')")
.GetCompletionValue().ToObject() as IEnumerable<VirtualProduct>;
using Jint;

var engine = new Engine()
.SetValue("products", Products);

var filteredProducts = engine.Execute("products.filter(p => p.Description.includes('toy') || p.URL === 'BestToyInAmerica.com')")
.GetCompletionValue().ToObject() as IEnumerable<VirtualProduct>;
friedice
friedice2y ago
I dont get the context. So in the front end, the user already has the entire list of VirtualProducts, and you want to filter them based on certain criterias that the user inputs?
JakenVeina
JakenVeina2y ago
I could interpret this two ways A) you want to re-invent SQL (I.E. you want SQL) B) you want to build a GUI
oe
oeOP2y ago
Neither. I want to dynamically filter the IEnumerable<VirtualProduct> or IEnumerable<VirtualStore> in a way that anyone who doesn't understand coding can write. They can create certain filters based on criteria. Like this VirtualProduct MUST contain "test" in the Description @ReactiveVeina @IceGPT
JakenVeina
JakenVeina2y ago
yes, and you said you want this to be a "language" that already exists, that's SQL
oe
oeOP2y ago
"some language or query" it can be anything really, just as simple as possible
JakenVeina
JakenVeina2y ago
SQL is as simple as it gets for this kinda thing any simpler (from the user's perspective), and it becomes drastically MORE complex to implement
oe
oeOP2y ago
eventually i will turn it into a GUI, so i'm unsure as to whether SQL is the best choice
JakenVeina
JakenVeina2y ago
if this is a stopgap, then I think SQL queries are your best bet sanitized, of course
oe
oeOP2y ago
its a solution for my company only
JakenVeina
JakenVeina2y ago
it's a reasonable compromise between ease of implementation, and burden on the user yeah, the user is gonna have to learn a little bit
oe
oeOP2y ago
what about this? @ReactiveVeina vs SQL seems easier to follow no? p.Description.includes('toy')
JakenVeina
JakenVeina2y ago
but how do you GET to that?
oe
oeOP2y ago
with Jint? what do you mean?
JakenVeina
JakenVeina2y ago
how so you get the value of "toy" out of the user's input, and determine that the user's intent is to apply it to the "Description" column? if the user's input is freeform text that you have to parse?
oe
oeOP2y ago
yes it is eventually, when i have that GUI i would do something like $"p.{Type}.includes('{SearchTerm}') Something like that
JakenVeina
JakenVeina2y ago
right the GUI wpuld be what parses it or, rather, makes the user pre-parse it for you
oe
oeOP2y ago
yeap
JakenVeina
JakenVeina2y ago
in a sense
oe
oeOP2y ago
i think i would rather take the JS approach instead of SQL because if i ever need to do some complex custom filtering logic it would be easier to implement in JS
Google
Google2y ago
More data going over the wire that’s unnecessary
oe
oeOP2y ago
only issue is now when i execute this query (filterQuery):
stores.Select(store => new VirtualStore { Name = store.Name, Products = store.Products.Where(product => product.StockNumber == "2").ToList() }).ToList();
stores.Select(store => new VirtualStore { Name = store.Name, Products = store.Products.Where(product => product.StockNumber == "2").ToList() }).ToList();
with this:
public List<VirtualStore>? FilterStores(string filterQuery, List<VirtualStore> stores)
{
var engine = new Engine()
.SetValue("stores", stores);

return (engine.Execute(filterQuery)
.GetCompletionValue().ToObject() as List<VirtualStore>);
}
public List<VirtualStore>? FilterStores(string filterQuery, List<VirtualStore> stores)
{
var engine = new Engine()
.SetValue("stores", stores);

return (engine.Execute(filterQuery)
.GetCompletionValue().ToObject() as List<VirtualStore>);
}
i get this error:
Jint.Parser.ParserException: 'Line 1: Unexpected token >'
Jint.Parser.ParserException: 'Line 1: Unexpected token >'
what do you mean?
JakenVeina
JakenVeina2y ago
I think he's assuming you're doing the filtering in JS, instead of sending the criteria down to the API
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server