JavaScript troubleshooting — structuredClone is not defined

Uncaught ReferenceError: StructuredClone is not defined

The error is because structuredClone() is not supported in the browser. For example, structuredClone() is not supported on Safari iOS until v15.4(Released in 2022) and it is not supported on IE at all.

To add compatible structuredClone() support in all browsers, you can define a manual deep copy function or use an existing one of a JavaScript library, like copyDeep of Lodash, clone() of Ramda.

Solution 1 — use user defined deep copy function

A user-defined deep copy function which is compatible with IE browser:

if (!window.structuredClone) {
    function myDeepCopy(value) {
        if (Array.isArray(value)) {
            var count = value.length;
            var arr = new Array(count);
            for (var i = 0; i < count; i++) {
                arr[i] = myDeepCopy(value[i]);
            }

            return arr;
        } else if (typeof value === 'object') {
            var obj = {};
            for (var prop in value) {
                obj[prop] = myDeepCopy(value[prop]);
            }

            return obj;
        } else { // Primitive value
            return value;
        }
    }

    window.structuredClone = myDeepCopy;
}

Solution 2 — use cloneDeep() of Lodash

Lodash is a modern JavaScript utility library. It is released under the MIT license & supports modern environments.

cloneDeep(value) creates a deep clone of value.

Example (Use lodash as a ES6 module):

// In ES6 module style:
import _ from 'lodash';
// Or you can just import the function you need
// import cloneDeep from "lodash/cloneDeep";

var objects = [{ 'a': 1 }, { 'b': 2 }];

var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false

Further reading

Reference

JavaScript troubleshooting — Failed to read the loacalStorage

Although localStorage API is available in current versions of all major browsers, the user may still encounter the exception Failed to read the 'localStorage' for localStorate has been disabled in browser settings. Like on Chrome, the user can check “Block cookies” option in the privacy settings to make localStorage is blocked too.

Therefore it is necessary to detect the availability of localStorage to fix the issue.

Uncaught DOMException: Failed to read the ‘localStorage’ property from ‘Window’

The full error message is:

Uncaught DOMException: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.

Solution

MDN provides a  a function that detects whether localStorage is both supported and available:

function storageAvailable(type) {
    var storage;
    try {
        storage = window[type];
        var x = '__storage_test__';
        storage.setItem(x, x);
        storage.removeItem(x);
        return true;
    }
    catch(e) {
        return e instanceof DOMException && (
            // everything except Firefox
            e.code === 22 ||
            // Firefox
            e.code === 1014 ||
            // test name field too, because code might not be present
            // everything except Firefox
            e.name === 'QuotaExceededError' ||
            // Firefox
            e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
            // acknowledge QuotaExceededError only if there's something already stored
            (storage && storage.length !== 0);
    }
}

Then you access localStorage only if it is available.

let isStorageAvailable = storageAvailable();
if (isStorageAvailable) {
    // Access localStorage
}

Further reading

  • JavaScript storage

    This post introduces modern Web data storage like sessionStorage, localStorage, IndexedDB, Cache, etc, as well as their applicable scenarios.

Reference