woocommerce / woocommerce-google-analytics-integration

WordPress plugin: Provides the integration between WooCommerce and Google Analytics.
http://wordpress.org/plugins/woocommerce-google-analytics-integration/
170 stars 69 forks source link

Product id reading issue for variable product add-to-cart(AJAX) #451

Closed sagarnasit closed 1 month ago

sagarnasit commented 1 month ago

Describe the bug:

The plugin displays an error when clicking the add-to-cart button for the variable product. This occurs only when using the ajax add-to-cart button.

Steps to reproduce:

  1. Activate plugin and set GA tracking id.
  2. Use AJAX for add-to-cart products.
  3. Add variable product with multiple variations.
  4. On the single product page, choose a product variation from the dropdown and then click on the add-to-cart button.

Expected behavior:

The plugin should be able to read the product id.

Actual behavior:

The plugin is not able to read product id for variable products.

Additional details:

Plugin cannot retrieve the product id from the button element for a variable product because the variable product id is set via a hidden input rather than the button value attribute.

Screenshot:

image
tomalec commented 1 month ago

Hi @sagarnasit :) Thanks for reporting an issue. Unfortunately, I was not able to reproduce it. Have you tested it with only WooCommerce and Google Analytics for WooCommerce, without any other extensions? Or maybe you could share more detailed steps to reproduce or a link to the shop with such an issue?

sagarnasit commented 1 month ago

Hi @tomalec

I have tested on fresh setup with WooCommerce and Google Analytics for WooCommerce plugins. I noticed Google Analytics Tracking ID settings field should be configured and it does not work if you logged in as admin.

Apart from that, the only condition is to use AJAX for add-to-cart. I'm using following script to handle AJAX.

jQuery(function ($) {

    // Open external product in new tab
    $( document ).find( '.product.product-type-external form.cart' ).attr( 'target', '_blank' );

    const addToCart = function ( e ) {
        e.preventDefault();

        const form = $( this ),
            button = form.find( '.single_add_to_cart_button' ),
            quantity = form.find( 'input[type="number"].qty' ).val(),
            isVariation = form.hasClass( 'variations_form' ) ?? false,
            variationValue = form
                .find( 'input[type="hidden"].variation_id' )
                .val(),
            attributeValue = form.find( 'select[name="attribute_amount"]' ).val();

        const data = {};
        data.product_id = isVariation
            ? Number( form.data( 'product_id' ) )
            : Number( button.val() );
        data.quantity = quantity ? Number( quantity ) : 1;

        if ( isVariation && variationValue ) {
            data.product_id = Number( variationValue );
        }

        if ( isVariation && attributeValue ) {
            data.attribute_amount = attributeValue;
        }

        // Abort if don't have required data
        if ( ! data.product_id || ! data.quantity ) {
            return;
        }

        button.removeClass( 'added' );
        button.addClass( 'loading' );

        $( document.body ).trigger( 'adding_to_cart', [ button, data ] );

        $.ajax( {
            type: 'POST',
            url: woocommerce_params.wc_ajax_url
                .toString()
                .replace( '%%endpoint%%', 'add_to_cart' ),
            data: data,
            success: function ( response ) {
                if ( ! response ) {
                    return;
                }

                // Redirect to cart option
                if ( wc_add_to_cart_params.cart_redirect_after_add === 'yes' ) {
                    window.location = wc_add_to_cart_params.cart_url;
                    return;
                }

                $( document.body ).trigger( 'added_to_cart', [
                    response.fragments,
                    response.cart_hash,
                    button,
                ] );
            },
            complete: function () {
                form.unblock();
            },
        } );
    };

    $( document ).on( 'submit', '.product:not(.product-type-external) form.cart', addToCart );
} );
tomalec commented 1 month ago

Thanks for the details.

I noticed Google Analytics Tracking ID settings field should be configured and it does not work if you logged in as admin.

Yes, Tracking ID is required for most of the extension functionality. Also, this is the desired behavior not to track admin action not to skew the analytics reports.

Apart from that, the only condition is to use AJAX for add-to-cart. I'm using following script to handle AJAX.

Do I read it right? This is not the native WooCommerce AJAX behavior enabled by the settings: image

But your custom code, correct?

If so, you need to fix that snippet to provide the product data:

button.dataset.product_id = data.product_id;

Before firing added_to_cart event.

Please let me know if that helps.

sagarnasit commented 1 month ago

@tomalec Yes, it's a custom code that I'm using.

I tried your suggestion but it did not work with the following error.

TypeError: Cannot set properties of undefined (setting 'product_id')

On a simple product, the add-to-cart button is expected to have a value attribute with the product_id. I tried the following, which worked for me, but I'm not sure if that's the correct approach.

button.attr('value', data.product_id);
tomalec commented 1 month ago

Sorry, I was using the native DOM API. To set the dataset for the jQuery object, you need to use jQuery API:

button.data( 'product_id', data.product_id );
sagarnasit commented 1 month ago

@tomalec It's showing the same error using jQuery API too.

tomalec commented 1 month ago

Maybe then stick to vanilla API and just fetch the native object out of the jQuery collection:

button[0].dataset.product_id = data.product_id;
tomalec commented 1 month ago

I'm closing this issue as answered. If it still does not work, feel free to reopen.