【问题标题】:How to filter products by productType on Shopify?如何在 Shopify 上按 productType 过滤产品?
【发布时间】:2022-01-22 22:13:19
【问题描述】:

希望用户能够使用菜单中的按钮通过productType 过滤产品。

目前我正在查询 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 还包含一个获取商店中所有产品类型的函数。

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
}

然后shop.js 循环遍历所有productTypes 并将它们显示在菜单中。它还循环遍历所有产品。

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,
      },
    }
  }

当用户尝试点击过滤器时,会出现以下错误。

TypeError: getProductsInCollection(...).filter 不是函数

让过滤器工作以使菜单过滤以下产品的正确方法是什么?

【问题讨论】:

  • getProductsInCollection()是一个异步函数,返回一个Promise,你需要await它,然后过滤filter函数内部的结果,即let filtredProducts = (await getProductsInCollection()).filter(product =&gt; product.node.productType === type);。这将使filter 函数也异步,因此请相应地修改您的代码。

标签: javascript next.js shopify


【解决方案1】:

您试图在 Promise 上调用 .filter(),而不是数组。尝试像这样修改您的代码:

export async function filter(type) {
  let products = await getProductsInCollection();
  let filteredProducts = products.filter(product => product.node.productType === type);
  return filteredProducts;
}

请记住,在调用filter() 时,您需要再次使用await,因为它现在也是一个异步函数。

【讨论】:

  • 感谢@Nils - 由于您的代码,它可以在控制台中正确打印,但是当我尝试通过 shop.js 中的过滤产品循环过滤器时,我收到以下错误“filtredProducts.map is not一个函数”有什么想法吗?谢谢!
【解决方案2】:

getProductsInCollection 返回 promise,在过滤器之前使用 async/await。

在 shop.js 中,您还必须在设置状态之前使用 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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    相关资源
    最近更新 更多