Skip to content

URL pre-selection of configurable product swatches with associated product images throws JavaScript error #18017

@leoquijano

Description

@leoquijano

Summary

When pre-selecting a configurable product swatch that has an image, Magento will try to load that image in the product gallery before it is initialized, throwing a JavaScript error.

This issue was already reported in #12517, but that bug is closed. I think that the fix I propose below is a better one, since it uses an event name that seems to be created for a similar purpose.

Preconditions

  1. Magento v2.2.5.
  2. PHP v7.1.20-1.
  3. Ubuntu 16.04.1
  4. Apache 2.4.18
  5. MySQL 5.7.23

Steps to reproduce

  1. Set up a default Magento instance, and create a configurable product with at least one option.
  2. Configure that option to use swatches (text or visual).
  3. Create at least one simple product associated to that option.
  4. Upload image A as default for the configurable product.
  5. Upload a different image B as default for the simple product.
  6. Make sure that Magento automatically loads the simple product image for the PDP gallery when the option is selected.
  7. Open the configurable product page, with the option pre-selected. For example: https://magento.app/sample-product.html#89=1245
  8. The Swatch Renderer will pre-select that swatch. Since Magento is configured to load its image (image B) when the swatch is selected, this image will be loaded.
  9. However, since we haven't loaded the gallery yet, the swatch renderer will throw an error when trying to load the image.

Expected result

  1. The swatch is selected and its associated simple product image is loaded in the gallery.

Actual result

  1. The swatch is not selected and the JavaScript console shows an error.

Investigation

The problem seems to be located in Module_Swatches::view/frontend/web/js/swatch-renderer.js. The following sequence of method calls is performed when pre-selecting a simple product:

  1. [Line 304] - Call to this._renderControls() - from the _init method.
  2. [Line 465] - Call to $widget._EmulateSelected($widget._getSelectedAttributes()).
  3. [Line 1243] - The click event is triggered with the attribute code, via $.proxy.
  4. [Line 619] - The click event is handled by _EventListener(), and the _OnClick() method is called.
    Note:
    • The _OnClick is called with two arguments: $(this), and $widget.
    • The emulateClick event is also available, and will call _OnClick with a third parameter, the event name (emulateClick).
  5. [Line 725] - The _loadMedia method is called by OnClick, to load the simple product image. Since the click event was used, and not emulateClick, the event name will be undefined.
  6. [Line 674] - The updateBaseImage method is called, with an undefined eventName argument.
  7. [Line 1156] - The processUpdateBaseImage is called, using an undefined gallery object. Note that if the event name is undefined (as in this case), the updateBaseImage method won't wait until the gallery image is loaded to process the image.
  8. [Line 1187] - The processUpdateBaseImage method will try to call gallery.updateData with the updated images, triggering the JavaScript error.
  • This error not only means that the image won't be loaded, but also that the swatch option won't be pre-selected, as expected.
  • It seems that the emulateClick event was created to avoid this issue (see commit 97390b3), but it's not being used for this use case.

Probable fix:

  • In the _EmulateSelected method described above (line 1243), use the emulateClick event instead of click:

    _EmulateSelected: function (selectedAttributes) {
      $.each(selectedAttributes, $.proxy(function (attributeCode, optionId) {
        this.element.find('.' + this.options.classes.attributeClass +
          '[attribute-code="' + attributeCode + '"] [option-id="' + optionId + '"]').trigger('emulateClick');
        }, this));
    },

Metadata

Metadata

Assignees

Labels

Component: SwatchesFixed in 2.3.xThe issue has been fixed in 2.3 release lineIssue: Clear DescriptionGate 2 Passed. Manual verification of the issue description passedIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedIssue: Format is validGate 1 Passed. Automatic verification of issue format passedIssue: Ready for WorkGate 4. Acknowledged. Issue is added to backlog and ready for developmentReproduced on 2.2.xThe issue has been reproduced on latest 2.2 releaseReproduced on 2.3.xThe issue has been reproduced on latest 2.3 release

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions