Unable to sort or filter by productVariant's price
See original GitHub issueDescribe the bug
I’m writing a frontend for Vendure backed website. I was using 0.17
version from @vendure/create
with stock items, on SQLite. For some reason I couldn’t get it to work after PC reboot, so I have recreated repository using create
. Now it’s running version 0.18
and my previous queries don’t work. I looked through Changelog and Blog but I don’t see a direct or indirect tip that this should break.
To Reproduce My query:
query ProductsForCollection(
$slug: String
$filters: ProductVariantFilterParameter
$sort: ProductVariantSortParameter
) {
collection(slug: $slug) {
name
slug
description
productVariants(options: { filter: $filters, sort: $sort }) {
items {
product {
name
assets {
name
source
}
id
slug
description
}
price
}
totalItems
}
}
}
Example variables:
- when only
slug
is provided it works. - when sort like below is provided it throws
{"variables":{"slug":"electronics","filters":{},"sort":{"price":"ASC"}}}
Expected behavior It should filter / sort properly I believe.
Environment (please complete the following information):
- @vendure/core version:
0.18.1
- Nodejs version:
14.15.0
- Database (mysql/postgres etc):
SQLite
Additional context Fanatastic work on the software. It’s exactly how I would’ve thought it out, but probably couldn’t build. 😃
Issue Analytics
- State:
- Created 3 years ago
- Comments:13 (6 by maintainers)
Top Results From Across the Web
No results found
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
All sorting & filtering queries are auto-generated by the ListQueryBuilder class.
This works by introspecting the TypeORM column metadata (getColumnMetadata()) and dynamically builds a query using the TypeORM QueryBuilder interface.
So the problem comes when we have e.g. the
price
field of ProductVariant: https://github.com/vendure-ecommerce/vendure/blob/ae07134185e53b557c88488b475c18c59eb39e35/packages/core/src/entity/product-variant/product-variant.entity.ts#L72-L78This is a getter, calculated at run-time (this is necessary because the actual price is channel-dependent and lives in another table, ProductVariantPrice).
So when introspecting TypeORM column metadata, there is no “price” column, hence the error.
Now, since those calculated fields can contain arbitrary JS logic to come up with the values, it’s not possible to create some automatic way to know how to sort based on that field. E.g. with the ProductVariant.price, what we really need to do is JOIN the ProductVariantPrice table, and then sort based on the value of ProductVariantPrice.price.
So my current idea is to implement some way of defining the custom sorting/filtering logic associated with each calculated field (actually, only those calculated fields which return primitive values). This might be in the form of a function which returns parameters understood by the TypeORM QueryBuilder API.
Then, the ListQueryBuilder can use that custom function when it needs to sort on that field. That’s the high-level idea, the implementation will probably be quite difficult to get right. In some instances (e.g. the Order.totalQuantity field) it will be really challenging to implement I think.
Any other ideas welcome!
Got it. Hmm yeah there might be a regression here, I’ll look into it!