• Resolved jozbelio

    (@jozbelio)


    Hi Pixel Manager team,

    First of all, thank you for a great plugin! It has saved us an enormous amount of time setting up conversion tracking. We have, however, stumbled upon a bug we want to report. I believe this bug is not specific to my environment but is a bug in your plugin.

    Environment: Pixel Manager for WooCommerce (free, v1.67.0), WooCommerce (10.9.4), Flatsome theme with child theme.

    The bug is, in short, that remove-from-cart tracking is broken due to a mismatch in how cart_item_keys are handled, which produces the “Wasn’t able to retrieve a productId” error message. Let me describe this in detail.

    When a customer removes a product from the cart (mini-cart, cart and checkout), the Js-console in Chrome show the following error:

    Pixel Manager: error: Error: Wasn't able to retrieve a productId
    at e.removeProductFromCart (functions.js:171)
    at HTMLAnchorElement.<anonymous> (event_listeners.js:159)

    This results in the pmw:remove-from-cart event nevr being sent.

    Steps to reproduce: Add any product to the cart, then load any page with the product in the cart, finally click a remove-from-cart button/link.

    Root cause: I had a long debug session where I managed to trace where things go wrong. A data-format mismatch inside the plugin between the backend cart sync and the remove-link resolver:

    1. ajax_pmw_get_cart_items() returns cart item keys as cart_item_keys[key] = { id, is_variation, parent_id }

    // class-pixel-manager.php
    $data['cart'][$product->get_id()]['variant'] = (string) implode( ' | ', $variant_text_array );
    $data['cart_item_keys'][$cart_item]['parent_id'] = (string) $product->get_parent_id();
    $data['cart_item_keys'][$cart_item]['is_variation'] = true;

    2. pmw.getCartItemsFromBackend() and pmw.reconcileCartFromBackend() in src/js-src/public/pmw/functions.js merge that response into pmwDataLayer.cart_item_keys via Object.assign, overwriting the { product_id, variation_id } entries that the inline cart-fragment scrips printed on page load by includes/pixels/class-pixel-manager.php.

    // includes/pixels/class-pixel-manager.php
    <script>
    (window.pmwDataLayer = window.pmwDataLayer || {}).cart_item_keys = window.pmwDataLayer.cart_item_keys || {};
    window.pmwDataLayer.cart_item_keys['<?php
    echo esc_js( $cart_item_key );
    ?>'] = <?php
    echo wp_json_encode( $data, $json_encode_options );
    ?>;
    </script>

    // src/js-src/public/pmw/functions.js</span>
    if (pmwDataLayer.cart_item_keys[cartItemKey]["variation_id"] === 0) {
    productId = pmwDataLayer.cart_item_keys[cartItemKey]["product_id"];
    } else {
    productId = pmwDataLayer.cart_item_keys[cartItemKey]["variation_id"];
    }

    3. pmw.getProductIdByCartItemKeyUrl() still reads the old fields, but since the “variation_id” key was overwritten, the productId will be undefined “variation_id” does not exist in the cart_item_keys[cartItemKey] associative array.

    // product-detection.js
    if (pmwDataLayer.cart_item_keys[cartItemKey]["variation_id"] === 0) {
    productId = pmwDataLayer.cart_item_keys[cartItemKey]["product_id"];
    } else {
    productId = pmwDataLayer.cart_item_keys[cartItemKey]["variation_id"];
    }

    This explains why the “Wasn’t able to retrieve a productId” error was thrown.

    Happy to provide debug logs or more details if useful. Thanks again for a fantastic plugin!

    • This topic was modified 3 weeks, 2 days ago by jozbelio.
    • This topic was modified 3 weeks, 2 days ago by jozbelio.
Viewing 4 replies - 1 through 4 (of 4 total)
  • Plugin Author SweetCode

    (@alekv)

    Hi jozbelio,

    Thank you for the exceptionally good bug report. Your analysis is correct on all three points, and we have gone through it and reproduced the problem exactly as you described.

    To confirm what you found: pmwDataLayer.cart_item_keys is written by two different places that did not agree on the format. The inline script next to each cart item writes product_id and variation_id, while the pmw_get_cart_items AJAX response writes id, is_variation and parent_id. Since getCartItemsFromBackend() and reconcileCartFromBackend() merge that response over the inline entries whole entry by whole entry, a cart sync left getProductIdByCartItemKeyUrl() reading two fields that no longer existed, which is the “Wasn’t able to retrieve a productId” you saw.

    What decides whether a shop runs into it is whether that cart sync happens at all. It runs whenever the WooCommerce cart hash has changed without one of the plugin’s own tracked events, which is the case after every non-AJAX add to cart. That is why your steps reproduce it every time, and it is also why our test suite never caught it: the tests add to the cart over AJAX, where the stored hash stays in step and the backend fetch never runs.

    Three things have changed:

    the AJAX endpoint now sends product_id and variation_id as well, so both sources write the same format the reader accepts either format, and returns nothing instead of throwing when a cart item key is missing altogether both remove paths now fall back to the product ID that WooCommerce puts on the remove control itself, which also covers cached cart fragments and themes that render their own cart markup.

    The fix is part of 1.67.1 and is already in the current beta, 1.67.1-beta.7. If you would like to verify it on your site before the stable release, let us know and we will get the beta build to you.

    Thanks again for reading through the code and pinpointing it, that turned this into a very quick fix.

    • This reply was modified 3 weeks, 2 days ago by SweetCode.
    • This reply was modified 3 weeks, 2 days ago by SweetCode.
    Thread Starter jozbelio

    (@jozbelio)

    Hi @alekv, that is great to hear! I a can absolutely test the beta so we know this is fixed on my end as well. How do I download the beta?

    As a side note: getting a reply AND a fix to the bug less than 2 hrs from hitting send really amazing! Thank you!

    Plugin Author SweetCode

    (@alekv)

    You can download the latest beta version from here: download

    Let me know if you need instructions on how to install it.

    Thread Starter jozbelio

    (@jozbelio)

    Can confirm, bug fixed in 1.67.1-beta.7. Marking this as resolved 🙂

Viewing 4 replies - 1 through 4 (of 4 total)

You must be logged in to reply to this topic.