Reputation: 2504
I am trying to filter a result using an array and it should follow the order of the filter array.
Here's my array which will be used for filtering.
// gatsby-node.js
// Fetch all collections
const collections = await graphql(`
{
allContentfulCollection {
edges {
node {
handle
productLists {
slug
handles
}
}
}
}
}
`);
collections.data.allContentfulCollection.edges.forEach((collection) => {
const { handle, productLists } = collection.node;
if (productLists.length) {
const defaultList = productLists.find(
(productList) => productList.slug === 'default'
);
// example defaultList.handles =
// [
// 'test-handle-a',
// 'test-handle-b',
// 'test-handle-c',
// 'test-handle-d'
// ];
createPage({
path: `/collections/${handle}`,
component: path.resolve('./src/templates/collection.js'),
context: {
handle,
handles: defaultList && defaultList.handles // this will be used to filter
}
});
}
});
...
// templates/collection.js
export const query = graphql`
query ProductInCollection($handles: [String], $handle: String) {
allContentfulProduct(filter: { handle: { in: $handles }, availableForSale: { eq: true } }) {
edges {
node {
handle
}
}
}
...
The graphql result does not follow the sort of $handles
array.
For example, the handle field which I get like the image is
[
'test-handle-b', // this is matching result with test-handle-a
'test-handle-d', // ...
'test-handle-c', // ...
'test-handle-a', // ...
]
// I expect to get the query result with the same order to the `$handles` in the query filter like below.
[
'test-handle-a',
'test-handle-b',
'test-handle-c',
'test-handle-d'
]
As you can see, I want to follow the ordering of the handles
array, but I get an unexpected result like the above example.
How can I get the result with sort of the handles
array?
Thank you.
Upvotes: 0
Views: 1237
Reputation: 29320
It should take the filter order as it is. Are you sure that it always has the same order? Does it always contain the same information in the same order? Do they have any rules that you can use to sort them?
In your case, I'd try:
createPage({
path: `/collections/${handle}`,
component: path.resolve('./src/templates/collection.js'),
context: {
handle,
handles.sort() // add an specific rule if any
}
});
Moreover, you can try sorting the output via GraphQL sort
:
// templates/collection.js
export const query = graphql`
query ProductInCollection($handles: [String], $handle: String) {
allContentfulProduct(filter: { handle: { in: $handles }, availableForSale: { eq: true } }, sort: { fields: [handle, $handles], order: ASC }) {
edges {
node {
description
handle
title
}
}
}
...
Despite adding the sorting in the GraphQL or JavaScript logic, I'd ensure that it has always the exact order. Additionally, if you can access the source of that array, you can try adding an order
field to each array element.
Upvotes: 2