[英]How to filter products by productType on Shopify?
The desired behaviour is for users to be able to filter products by their productType
using buttons in a menu.期望的行为是让用户能够使用菜单中的productType
按产品类型过滤产品。
At the moment I'm querying the Shopify storefront API and fetching back products in lib/Shopify.js
目前我正在查询 Shopify 店面 API 并在lib/Shopify.js
中取回产品
export async function getProductsInCollection() {
const query = `
{
collectionByHandle(handle: "frontpage") {
title
products(first: 25) {
edges {
node {
id
title
productType
handle
}
}
}
}
}`
const response = await ShopifyData(query)
const allProducts = response.data.collectionByHandle.products.edges ? response.data.collectionByHandle.products.edges : []
return allProducts
}
export function filter(type) {
let filtredProducts = getProductsInCollection().filter(product => product.node.productType === type);
return filtredProducts;
}
lib/Shopify.js
also contains a function to fetch all the productTypes in the store. lib/Shopify.js
还包含一个 function 以获取商店中的所有产品类型。
export async function getProductTypes() {
const query =
`{
shop {
products(first:250, query:"-product_type:''") {
edges {
node {
productType
}
}
}
}
}`
const response = await ShopifyData(query)
const rawProductTypes = response.data.shop.products ? response.data.shop.products.edges : []
const productTypes = Array.from(new Set(rawProductTypes));
return productTypes
}
Then shop.js
loops through all of the productTypes and displays them in a menu.然后shop.js
循环遍历所有 productType 并将它们显示在菜单中。 It also loops through all of the products.它还循环遍历所有产品。
import { getProductsInCollection, getProductTypes, filter } from "../lib/shopify"
import React, { useState, useEffect } from "react";
import Link from 'next/link'
export default function Shop({ products, pages, projects, productTypes }) {
const [filtredProducts, setFiltredProducts] = useState(null);
useEffect(() => {
setFiltredProducts(getProductsInCollection());
}, []);
var categories = new Map();
productTypes.forEach( function( item ) {
categories.set(JSON.stringify(item), item);
});
function handleCategories(e) {
let type = e.target.value;
type !== "all"
? setFiltredProducts(filter(type))
: setFiltredProducts(getProductsInCollection());
}
const deduped = Array.from(new Set(productTypes));
return (
<div>
<div>
{categories &&
[...categories.values()].map((category, index) => (
<>
<button className="mr-8 mb-6 underline" key={index} value={category.node.productType} onClick={handleCategories}>
{category.node.productType}
</button>
</>
))}
{filtredProducts &&
filtredProducts.map(p => (
<ul>
<li>{p.node.title}</li>
</ul>
))}
</div>
</div>
)
}
export async function getStaticProps() {
const products = await getProductsInCollection()
const productTypes = await getProductTypes()
return {
props: {
products,
productTypes,
},
}
}
When the user tries to click on the filter they get the following error.当用户尝试单击过滤器时,他们会收到以下错误。
TypeError: getProductsInCollection(...).filter is not a function类型错误:getProductsInCollection(...).filter 不是 function
What's the correct way to get the filter to work so the menu filters the products below?什么是让过滤器工作的正确方法,以便菜单过滤下面的产品?
You are trying to call .filter()
on a Promise, not an array.您正在尝试在 Promise 上调用.filter()
,而不是数组。 Try modifying your code like this:尝试像这样修改您的代码:
export async function filter(type) {
let products = await getProductsInCollection();
let filteredProducts = products.filter(product => product.node.productType === type);
return filteredProducts;
}
Keep in mind, when calling filter()
you need to use await
again since it is now also an async function.请记住,在调用filter()
时,您需要再次使用await
,因为它现在也是异步 function。
getProductsInCollection returns promise, use async/await before the filter. getProductsInCollection 返回 promise,在过滤器之前使用 async/await。
In shop.js also you have to use async/await before setting to state.在 shop.js 中,您还必须在设置为 state 之前使用 async/await。
export async function getProductsInCollection() {
const query = `
{
collectionByHandle(handle: "frontpage") {
title
products(first: 25) {
edges {
node {
id
title
productType
handle
}
}
}
}
}`;
const response = await ShopifyData(query);
const allProducts = response.data.collectionByHandle.products.edges
? response.data.collectionByHandle.products.edges
: [];
return allProducts;
}
export async function filter(type) {
let filtredProducts = await getProductsInCollection();
return filtredProducts.filter((product) => product.node.productType === type);
}
// shop.js
async function handleCategories(e) {
let type = e.target.value;
let products = [];
if (type !== "all") {
products = await filter(type);
} else {
products = getProductsInCollection();
}
setFiltredProducts(products);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.