From 8d6514ab2f8c8d555f99893ad16b0c8e9f2cfd07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomek=20Wytr=C4=99bowicz?= Date: Mon, 24 Jun 2024 22:23:17 +0200 Subject: [PATCH 1/3] Add checks and explicit errors when cart buttons are missing data to help debugging issues with other extensions manipulating WC Core add & remove from cart buttons or events. --- assets/js/src/integrations/classic.js | 40 +++++++++++++++++++++------ 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/assets/js/src/integrations/classic.js b/assets/js/src/integrations/classic.js index a8dfad84..4fa3e820 100644 --- a/assets/js/src/integrations/classic.js +++ b/assets/js/src/integrations/classic.js @@ -60,14 +60,20 @@ export function classicTracking( } // Get product ID from data attribute (archive pages) or value (single product pages). const productID = parseInt( - button[ 0 ].dataset.product_id || button[ 0 ].value + button?.[ 0 ]?.dataset.product_id || button?.[ 0 ].value ); + if ( isNaN( productID ) ) { + throw new Error( + 'Google Analytics for WooCommerce: Could not read product ID from button given in `added_to_cart` event. Check whether WooCommerce Core events or elements are malformed by other extensions.' + ); + } + // If the current product doesn't match search by ID. const productToHandle = product?.id === productID ? product - : getProductFromID( parseInt( productID ), products, cart ); + : getProductFromID( productID, products, cart ); // Confirm we found a product to handle. if ( ! productToHandle ) { @@ -96,12 +102,15 @@ export function classicTracking( * @param {HTMLElement|Object} element - The HTML element clicked on to trigger this event */ function removeFromCartHandler( element ) { + const productID = parseInt( element.target?.dataset.product_id ); + + if ( isNaN( productID ) ) { + throw new Error( + 'Google Analytics for WooCommerce: Could not read product ID from the target element given to remove from cart event. Check whether WooCommerce Core events or elements are malformed by other extensions.' + ); + } getEventHandler( 'remove_from_cart' )( { - product: getProductFromID( - parseInt( element.target.dataset.product_id ), - products, - cart - ), + product: getProductFromID( productID, products, cart ), } ); } @@ -117,11 +126,24 @@ export function classicTracking( // Trigger the handler when an item is removed from the mini-cart and WooCommerce dispatches the `removed_from_cart` event. const oldOnRemovedFromCart = document.body.onremoved_from_cart; - document.body.onremoved_from_cart = function () { + /** + * Track the custom removed from cart event dispatched by WooCommerce Core + * + * @param {Event} e - The event object + * @param {Object} fragments - An object containing fragments of the updated cart. + * @param {string} cartHash - A string representing the hash of the cart after the update. + * @param {HTMLElement[]} button - An array of HTML elements representing the remove from cart button. + */ + document.body.onremoved_from_cart = function ( + e, + fragments, + cartHash, + button + ) { if ( typeof oldOnRemovedFromCart === 'function' ) { oldOnRemovedFromCart.apply( this, arguments ); } - removeFromCartHandler( { target: arguments[ 3 ][ 0 ] } ); + removeFromCartHandler( { target: button?.[ 0 ] } ); }; // Handle product selection events. From 45b9a809882eac97525c068723baa23c7c3bf999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomek=20Wytr=C4=99bowicz?= Date: Tue, 25 Jun 2024 19:30:51 +0200 Subject: [PATCH 2/3] Consider cases where button is an empty jQuery collection Address https://github.com/woocommerce/woocommerce-google-analytics-integration/pull/443#discussion_r1651954213 Fix grammar in the error message. --- assets/js/src/integrations/classic.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/src/integrations/classic.js b/assets/js/src/integrations/classic.js index 4fa3e820..4967bc54 100644 --- a/assets/js/src/integrations/classic.js +++ b/assets/js/src/integrations/classic.js @@ -60,12 +60,12 @@ export function classicTracking( } // Get product ID from data attribute (archive pages) or value (single product pages). const productID = parseInt( - button?.[ 0 ]?.dataset.product_id || button?.[ 0 ].value + button?.[ 0 ]?.dataset.product_id || button?.[ 0 ]?.value ); if ( isNaN( productID ) ) { throw new Error( - 'Google Analytics for WooCommerce: Could not read product ID from button given in `added_to_cart` event. Check whether WooCommerce Core events or elements are malformed by other extensions.' + 'Google Analytics for WooCommerce: Could not read product ID from the button given in `added_to_cart` event. Check whether WooCommerce Core events or elements are malformed by other extensions.' ); } From 9e2060c95638c9285782f8ebc976d14997c0347b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomek=20Wytr=C4=99bowicz?= Date: Tue, 25 Jun 2024 19:32:56 +0200 Subject: [PATCH 3/3] Use `Number.isNaN` as a safer alternative to `isNaN` Address https://github.com/woocommerce/woocommerce-google-analytics-integration/pull/443#discussion_r1651961681 --- assets/js/src/integrations/classic.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/src/integrations/classic.js b/assets/js/src/integrations/classic.js index 4967bc54..5d33c689 100644 --- a/assets/js/src/integrations/classic.js +++ b/assets/js/src/integrations/classic.js @@ -63,7 +63,7 @@ export function classicTracking( button?.[ 0 ]?.dataset.product_id || button?.[ 0 ]?.value ); - if ( isNaN( productID ) ) { + if ( Number.isNaN( productID ) ) { throw new Error( 'Google Analytics for WooCommerce: Could not read product ID from the button given in `added_to_cart` event. Check whether WooCommerce Core events or elements are malformed by other extensions.' ); @@ -104,7 +104,7 @@ export function classicTracking( function removeFromCartHandler( element ) { const productID = parseInt( element.target?.dataset.product_id ); - if ( isNaN( productID ) ) { + if ( Number.isNaN( productID ) ) { throw new Error( 'Google Analytics for WooCommerce: Could not read product ID from the target element given to remove from cart event. Check whether WooCommerce Core events or elements are malformed by other extensions.' );