Skip to content

Commit 993d89c

Browse files
milesmcleodmagento-bot
andauthored
fix: [MINT-4697] fix minicart updates categories fetching (#213)
* fix: [MINT-4697] fix minicart updates categories fetching * add try/catch handling * auto-changelog --------- Co-authored-by: magento-bot <[email protected]>
1 parent 6dda3c2 commit 993d89c

File tree

2 files changed

+68
-40
lines changed

2 files changed

+68
-40
lines changed

Controller/Minicart/Categories.php

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
namespace Extend\Integration\Controller\Minicart;
88

99
use Magento\Catalog\Api\CategoryRepositoryInterface;
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
1011
use Magento\Checkout\Model\Session as CheckoutSession;
1112
use Magento\Framework\App\Action\Context;
1213
use Magento\Framework\Controller\Result\JsonFactory;
14+
use Magento\Framework\Exception\NoSuchEntityException;
1315

1416
class Categories extends \Magento\Framework\App\Action\Action
1517
{
@@ -23,6 +25,11 @@ class Categories extends \Magento\Framework\App\Action\Action
2325
*/
2426
protected $categoryRepository;
2527

28+
/**
29+
* @var ProductRepositoryInterface
30+
*/
31+
protected $productRepository;
32+
2633
/**
2734
* @var JsonFactory
2835
*/
@@ -32,32 +39,42 @@ public function __construct(
3239
Context $context,
3340
JsonFactory $resultJsonFactory,
3441
CheckoutSession $checkoutSession,
35-
CategoryRepositoryInterface $categoryRepository
42+
CategoryRepositoryInterface $categoryRepository,
43+
ProductRepositoryInterface $productRepository
3644
) {
3745
$this->resultJsonFactory = $resultJsonFactory;
3846
$this->checkoutSession = $checkoutSession;
3947
$this->categoryRepository = $categoryRepository;
48+
$this->productRepository = $productRepository;
4049
parent::__construct($context);
4150
}
4251

4352
public function execute()
4453
{
4554
$items = [];
46-
$cart = $this->checkoutSession->getQuote();
47-
foreach ($cart->getAllVisibleItems() as $item) {
48-
$product = $item->getProduct();
49-
50-
if (!$product) {
51-
continue;
55+
// this endpoint now accepts a query parameter `product_ids` which is a comma-separated list of product ids.
56+
// this enables us to bypass a getQuote() call and simply get the category for the products specified in the request.
57+
if ($this->getRequest()->getParam('product_ids') !== null) {
58+
$productIds = array_filter(
59+
array_map('trim', explode(',', $this->getRequest()->getParam('product_ids'))),
60+
function ($id) {
61+
return $id !== '' && is_numeric($id);
5262
}
53-
54-
$categories = $product->getCategoryIds();
55-
$id = $item->getId();
56-
57-
if (count($categories) > 0) {
63+
);
64+
foreach ($productIds as $productId) {
65+
try {
66+
/** @var \Magento\Catalog\Model\Product $product */
67+
$product = $this->productRepository->getById($productId);
68+
$categories = $product->getCategoryIds();
69+
if (count($categories) === 0) {
70+
continue;
71+
}
5872
$category = $this->categoryRepository->get($categories[0]);
59-
$items[$id] = $category->getName();
73+
$items[$productId] = $category->getName();
74+
} catch (NoSuchEntityException $e) {
75+
continue;
6076
}
77+
}
6178
}
6279
$resultJson = $this->resultJsonFactory->create();
6380
return $resultJson->setData($items);

view/frontend/web/js/view/cart/minicart-updates.js

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,45 @@ define([
1515
const itemDetailsSelector = 'div.product-item-details'
1616
const simpleOfferClass = 'extend-minicart-simple-offer'
1717

18-
const handleUpdate = function () {
18+
const handleUpdate = async function () {
1919
const cartItems = cartUtils.getCartItems()
20-
let categories
2120

22-
cartItems.forEach(async cartItem => {
21+
const productIds = cartItems
22+
.filter(cartItem => {
23+
const isWarrantyInCart = ExtendMagento.warrantyInCart({
24+
lineItemSku: cartItem.product_sku,
25+
lineItems: cartItems,
26+
})
27+
return (
28+
cartItem.product_sku !== 'extend-protection-plan' &&
29+
cartItem.product_sku !== 'xtd-pp-pln' &&
30+
!isWarrantyInCart
31+
)
32+
})
33+
.map(cartItem => cartItem.product_id)
34+
.join(',')
35+
36+
if (!productIds) {
37+
return
38+
}
39+
40+
const categories = await new Promise((resolve, _reject) => {
41+
$.ajax({
42+
url: window.BASE_URL + 'extend_integration/minicart/categories',
43+
type: 'GET',
44+
data: { product_ids: productIds },
45+
dataType: 'json',
46+
success: function (response) {
47+
resolve(response)
48+
},
49+
error: function (xhr, status, error) {
50+
console.error(error)
51+
resolve({})
52+
},
53+
})
54+
})
55+
56+
cartItems.forEach(cartItem => {
2357
const isWarrantyInCart = ExtendMagento.warrantyInCart({
2458
lineItemSku: cartItem.product_sku,
2559
lineItems: cartItems,
@@ -49,29 +83,6 @@ define([
4983
} else {
5084
// TODO: If warranty already in cart, no need to render
5185

52-
// Only fetch categories if we actually get to the point of needing to render an offer
53-
// Once this is fetched once though we should never need to fetch categories again
54-
// for the current execution of handleUpdate.
55-
// Why Ajax? There's no JavaScript API to get categories in Magento and we can't use a
56-
// ViewModel because the minicart doesn't rerender in cases such as items being added to cart.
57-
if (!categories) {
58-
categories = await new Promise((resolve, _reject) => {
59-
$.ajax({
60-
url:
61-
window.BASE_URL + 'extend_integration/minicart/categories',
62-
type: 'GET',
63-
dataType: 'json',
64-
success: function (response) {
65-
resolve(response)
66-
},
67-
error: function (xhr, status, error) {
68-
console.error(error)
69-
resolve({})
70-
},
71-
})
72-
})
73-
}
74-
7586
simpleOfferElem = document.createElement('div')
7687
simpleOfferElem.setAttribute('id', simpleOfferElemId)
7788
simpleOfferElem.setAttribute('class', simpleOfferClass)
@@ -90,7 +101,7 @@ define([
90101
Extend.buttons.renderSimpleOffer('#' + simpleOfferElemId, {
91102
referenceId: cartItem.product_sku,
92103
price: cents,
93-
category: categories[cartItem.item_id],
104+
category: categories[cartItem.product_id],
94105
onAddToCart: function (opts) {
95106
addToCart(opts)
96107
},

0 commit comments

Comments
 (0)