Product Lists

Product lists can be used to implement wish lists, save for later lists, favourites, etc. A customer may add products (or product variants) to a list in order to save them for future purchase. Template Trend has an example implementation of "favourites" using product lists.

When a customer is logged in to their personal account, product lists will be saved to the database. If the customer is logged out or does not have an account, the list will be stored in localStorage. Once the customer logs in or signs up, the list will automatically be associated with their account.

Handling product variants

A list can contain both a mixture of "base products" and product variants. Imagine that a product, "T-shirt" has a Color option with the values Blue, Red, and Green. It is possible for a user to add the base product ("T-shirt") to the product list, without selecting a variant. A user can also select a variant ("Blue") and add that to their product list. The user could continue to add "Green" to the list as well.

If a user has added a base product to their list, they will later need to select a variant before they can add the product to their cart.

ProductListProvider

import { ProductListProvider } from @jetshop/core/hooks/ProductList/ProductListProvider

If you'd like to use the product lists feature, you will need to wrap your store in the ProductListProvider. The best place to do this is in your Shop.js.

Props

Prop Type Required? Description
queries ProductListQueries true An object containing all of the queries used for ProductLists.
initialState ProductListState false Used to override the initial product list state. For advanced usage - most useful for testing

ProductListQueries

A set of default queries to query and mutate product lists is available in template-trend/src/components/ProductList/productListQueries.js and it is imported for you in the Shop.js template.

You can customize and pass your own queries to ProductListProvider as long as you implement the ProductListQueries interface (check core/hooks/ProductList/index.ts):

Copy
Copied
const customQueries = {
   all: myqueries.GetAllLists,
   createList: myqueries.CreateNewList,
   // ... etc.
}

<ProductListProvider queries={customQueries}>
  {children}
</ProductListProvider>

Provided values

Type Description
createList(name:string) => void Create a new product list.
deleteList(listId:string) => void Delete a product list.
state All product lists for the current user

Note: If you want to use product lists other than the default one, you need to explicitly create it with createList

useProductList

This hook can be used from any component inside the ProductListProvider. It provides the functions you can use to mutate the list, to check how many items are in the list, and whether a particular Product or ProductVariant is in the list.

Copy
Copied
const { toggle, add, remove, update, clear, inList, count, list } =
  useProductList();

Arguments

By default all actions are done on a default list. The default list doesn't need to be created explicitly and can be accessed by just calling the hook without arguments. You can optionally pass in a listId and all functions of the hook will be scoped to this list.

Argument Type Required? Description
listId string false The ID of the product list that you'd like to use.

Result

Property Type Description
toggle (articleNumber, { variantArticleNumber = null, quantity = 1, description = null }) => void Toggles (adds or removes) a Product or ProductVariant in the list. When acting on a variant, make sure to pass both the Product articleNumber and ProductVariant articleNumber
add (articleNumber: string, { variantArticleNumber = null, quantity = 1, description = null }): void Adds a Product or ProductVariant to the list
update (articleNumber, { variantArticleNumber = null, quantity = 1, description = null, variantToReplace = null }) => void Updates a Product or ProductVariant in the list. If replacing a ProductVariant with another, variantToReplace should be the articleNumber of the variant you'd like to replace
clear () => void Clears all items from the product list
inList (articleNumber, { variantArticleNumber = null }) => boolean Given an articleNumber and optional variantArticleNumber, returns a boolean indicating whether that Product or ProductVariant is in the list
count number Total number of items in the list
list NormalizedProductList Returns the normalized list. For advanced usage — mainly useful for testing

useProductListItems

This hook will return an array of all products that are in your product list. Unlike a normal products query, there will be a distinct item in the list for each product and each product variant in the product list.

Each item in the array will include the result of querying using the productsQuery that were specified in the options passed to ProductListProvider.

Copy
Copied
const { products, loading } = useProductListItems(listId, options);

Arguments

Argument Type Required? Description
listId string false The ID of the product list that you'd like to use.
options Options false Additional options

Options

Option Type Description
limit number Used to limit the amount of Products returned

Result

Property Type Description
loading boolean Whether a products query is in flight
products ProductListProduct[] An array of products in the list

Note

ProductsListProduct is an extension of the Product type. It adds the following fields to Product:

Parameter Type Description
quantity number The quantity for the item, as specified when adding the item to the list
isVariant boolean Whether or not the item is a variant
variant ProductVariant? If the item is a variant, this will include the details of the variant
validation ProductListProductValidation An object containing the validation status of the item. Can be used to determine whether the item can be added to the cart
Copy
Copied
type ProductListProductValidation = {
  status:
    | "valid"
    | "outOfStock"
    | "configurations"
    | "missingVariant"
    | "preOrder";
  message: string;
};

Tip

When adding a ProductListProduct to the cart, make sure to use the variant.articleNumber if isVariant is true. This ensures the variant and not the base product is added to the cart.

Copyright © Norce 2023. All right reserved.