I am using Azure Static Web App with Azure SQL database. When filtering the data, I want to use the in
instead of the eq
operator. So far the eq
operator is working as expected:
async function filterProducts() {
const query = `
query Products {
products(filter: { category: { eq: "dairy" } }) {
items {
date
category
price
}
}
}`;
const filteredProducts = await fetch('/data-api/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: query })
})
.then((response) => response.json())
.then((dataJson) => {
const dataItems = dataJson.data.products.items;
const dates = dataItems.map((product) => product.date);
const prices = dataItems.map((product) => product.price);
return { dates, prices };
})
.catch((err) => console.warn('Unable to fetch from the endpoint.', err));
return filteredProducts;
}
However, using the in
operator will get a 400 status (Bad Request) error. This is the input query:
const query = `
query Products {
products(filter: { category: { in: ["dairy", "fruit"] } }) {
items {
date
category
price
}
}
}`;
And I got the error when calling the localhost:4280/data-api/graphql
endpoint:
Failed to load resource: the server responded with a status of 400 (Bad Request)
Is it possible to use the in
operator from an Azure Static Web App? How to filter multiple values using GraphQL in Azure Static Web App?
The https://stackoverflow.com/a/78345944/10721627 answer is incomplete because it only retrieves 100 data by default. To gather all the data, we need to use the hasNextPage
as a return statement and reassign the afterCursor
to the endCursor
variable in each iteration.
async function filterProducts() {
let allProducts = [];
let pageSize = 1000;
let hasNextPage = true;
let afterCursor = null;
// Fetches all data from the endpoint using pagination.
while (hasNextPage) {
const query = `
query Products {
products(first: ${pageSize}, after: ${afterCursor}) {
items {
date
category
price
}
hasNextPage
endCursor
}
}
`;
await fetch('/data-api/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: query })
})
.then((response) => response.json())
.then((dataJson) => {
allProducts = allProducts.concat(dataJson.data.products.items);
hasNextPage = dataJson.data.products.hasNextPage;
afterCursor = `"${dataJson.data.products.endCursor}"`;
})
.catch((err) => {
console.warn('Unable to fetch the data from the `selectAllMaterialStock` endpoint.', err);
hasNextPage = false;
});
}
// Filters the data using the fields.
const categories = ['dairy', 'fruits'];
const filteredProducts = allProducts.filter((item) => categories.includes(item.category));
return filteredProducts;
}
We are appending the fetched data into the allProducts
array. Once we have the complete data, we can filter it with the built-in Array.prototype.filter() method since the in
operator cannot be used, see the previous answer.
Note: If there is huge data, this solution will not be the most performant alternative. A possible alternative could be to use the
mssql
package to directly query the database.