Magento 2.4.1 – Fix Uncaught TypeError: Cannot Read Property ‘remove’ of Undefined

javascriptmagento2.4.1undefined

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?

Best Answer

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();
Related Topic