8

Uncaught TypeError: Cannot read property 'remove' of undefined -- upgrade from 2.3.4 to 2.4.1

I'm testing out an upgrade of our Magento store from 2.3.4 to 2.4.1. One issue I have come across is this Javascript error that seems to occur on every page:

Uncaught TypeError: Cannot read property 'remove' of undefined
at customer-data.js:178
at Function._.each._.forEach (underscore.js:145)
at Object.remove (customer-data.js:177)
at Object.invalidate (customer-data.js:336)
at 1cc0eb0120ba46c0d78f41f8e5526a7e.js:4184
at Object.execCb (1cc0eb0120ba46c0d78f41f8e5526a7e.js:1650)
at Module.check (1cc0eb0120ba46c0d78f41f8e5526a7e.js:866)
at Module.<anonymous> (1cc0eb0120ba46c0d78f41f8e5526a7e.js:1113)
at 1cc0eb0120ba46c0d78f41f8e5526a7e.js:132
at 1cc0eb0120ba46c0d78f41f8e5526a7e.js:1156

This appears to come from the following section in customer-data.js:

/**
     * @param {Object} sections
     */
    remove: function (sections) {
        _.each(sections, function (sectionName) {
            storage.remove(sectionName);

            if (!sectionConfig.isClientSideSection(sectionName)) {
                storageInvalidation.set(sectionName, true);
            }
        });
    }

It seems like the Javascript failure is preventing other Javascript elements on the site from executing correctly. For example, Add to Cart buttons, tabs on the detail page, account creation form, all aren't loading properly. We do use a custom in-house theme, however, I switched to the stock Magento Luma theme, and the exact same issue is happening there, so it's not related to our theme.

Has anyone else seen this issue? Any ideas how to fix or work around it?

3
  • Not sure but if you want then wrap it into if condition where you have check if storage is not undefined like this storage === undefined Dec 23, 2020 at 8:02
  • can you please explain a little bit more Dec 23, 2020 at 8:59
  • Hey, you first need to know what is undefined, the remove is trying to do it's thing in something that is not defined, you should have somewhere "undefined.remove" being undefined something that you need to know to go debug, I think that Nilesh is saying is for you to check in "storage" is that undefined.
    – Rui Silva
    Dec 23, 2020 at 10:03

5 Answers 5

7

Inside the customer-data.js for Magento 2.4 (/vendor/magento/module-customer/view/frontend/web/js/customer-data.js), Magento have moved the storage initialisation. Instead of being available on a global level, they have now wrapped it.

If you do a Code Diff Check on Magento 2.3.6 customer-data.js compared with 2.4, you will see the differences. But for reference, Before:

enter image description here

After: enter image description here

There is an open issue on Github here: https://github.com/magento/magento2/issues/31920

In one of the comments, someone has referenced commits in fixing the problem: https://github.com/magento/magento2/commit/5983e1733d56b1b2f15fb4f0e64094a3a4f3145d

This can simply be applied as a Magento patch to address the issue. Add the following to a .patch file an apply via composer:

--- view/frontend/web/js/customer-data.js
+++ view/frontend/web/js/customer-data.js
@@ -17,7 +17,9 @@
 ], function ($, _, ko, sectionConfig, url) {
     'use strict';

-    var options = {},
+    var options = {
+            cookieLifeTime: 86400 //1 day by default
+        },
         storage,
         storageInvalidation,
         invalidateCacheBySessionTimeOut,
@@ -31,6 +33,22 @@
     options.sectionLoadUrl = url.build('customer/section/load');

     /**
+     * Storage initialization
+     */
+    function initStorage() {
+        $.cookieStorage.setConf({
+            path: '/',
+            expires: new Date(Date.now() + parseInt(options.cookieLifeTime, 10) * 1000),
+            samesite: 'lax'
+        });
+        storage = $.initNamespaceStorage('mage-cache-storage').localStorage;
+        storageInvalidation = $.initNamespaceStorage('mage-cache-storage-section-invalidation').localStorage;
+    }
+
+    // Initialize storage with default parameters to prevent JS errors while component still not initialized
+    initStorage();
+
+    /**
      * @param {Object} invalidateOptions
      */
     invalidateCacheBySessionTimeOut = function (invalidateOptions) {
@@ -216,15 +234,7 @@
         /**
          * Storage init
          */
-        initStorage: function () {
-            $.cookieStorage.setConf({
-                path: '/',
-                expires: new Date(Date.now() + parseInt(options.cookieLifeTime, 10) * 1000),
-                samesite: 'lax'
-            });
-            storage = $.initNamespaceStorage('mage-cache-storage').localStorage;
-            storageInvalidation = $.initNamespaceStorage('mage-cache-storage-section-invalidation').localStorage;
-        },
+        initStorage: initStorage,

         /**
          * Retrieve the list of sections that has expired since last page reload.
@@ -364,7 +374,10 @@
          */
         'Magento_Customer/js/customer-data': function (settings) {
             options = settings;
+
+            // re-init storage with a new settings
             customerData.initStorage();
+
             invalidateCacheBySessionTimeOut(settings);
             invalidateCacheByCloseCookieSession();
             customerData.init();
9

I was also getting this same issue.
As a temporary fix, I have copied customer-data.js from 2.3.4 to 2.4.1.
Magento has changed the storage initialization in custom-data.js.

UPDATE
I have debugged further and found that the following code

<script>
    require([
        'Magento_Customer/js/customer-data'
    ], function (customerData) {
        var sections = ['cart'];
        customerData.invalidate(sections);
        customerData.reload(sections, true);
    });
</script>

was the culprit.
In a third-party module, the above code was there in the phtml template file.

To fix the issue, I have created a new js file and added the following code.

require([
    'Magento_Customer/js/customer-data'
    ], function (customerData) {
    return function () {
        var sections = ['cart'];
        customerData.invalidate(sections);
        customerData.reload(sections, true);
    }
});
1
  • for my code it works also. I don't understand what return () { ... } wrapper has changed. Mar 25, 2021 at 16:43
5

I got it working by manually recreating the minicart.phtml file and place this script at the bottom of the file.

What I did differently was re-init-ing the Storage before I try to invalidate it, which did the trick for me.

        window.addEventListener('load', function () {
            require(['Magento_Customer/js/customer-data', 'domReady!'], function (customerData) {
                    var sections = ['cart'];
                    customerData.initStorage();
                    customerData.invalidate(sections);
                    customerData.reload(sections, true);
            });
        });
0

disable or switch theme not actually good check! Because you still have modules area that can affected to entire website. In specific case you can get issue in frontend with js error. You need to check that too(Any 3rd-party modules or customises)

0

You can apply this as a patch:

https://github.com/magento/magento2/pull/31940/files

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.