I have a class that returns a Proxy from the constructor. When I try to store instances of this class in IndexedDB, or send the object using window.postMessage()
, I receive an error stating that the object could not be cloned. It appears that the structured clone algorithm cannot handle Proxy objects.
The following code demonstrates the error:
class MyClass {
constructor() {
return new Proxy(this, {
set(target, prop, val, receiver) {
console.log(`"${prop}" was set to "${val}"`);
return Reflect.set(target, prop, val, receiver);
}
});
}
}
const obj = new MyClass;
try {
window.postMessage(obj,'*');
} catch(err) {
console.error(err);
}
Can anyone suggest a workaround for this problem? I see two potential solutions, but I don't know how I might implement them:
Do not return a Proxy from the constructor, but maintain the Proxy functionality within the class declaration somehow.
Alter the Proxy instance so that it works with the structured clone algorithm.
EDIT: The following, simpler code also demonstrates the structured clone error:
const p = new Proxy({}, {});
window.postMessage(p, '*');
You can save the original, non-proxied object in a class property, and use it when you want to pass it to postMessage
. You can change the constructor to have an optional parameter which will be passed to the proxy instead of this
. This way you can recreate the object by passing it to the constructor.
class MyClass {
constructor(original = this) {
this.original = original;
return new Proxy(original, {
set(target, prop, val, receiver) {
console.log(`"${prop}" was set to "${val}"`);
return Reflect.set(target, prop, val, receiver);
}
});
}
export() {
return this.original;
}
static import(original) {
return new MyClass(original);
}
}
const obj = new MyClass;
obj.test = 1;
console.log(MyClass.import(obj.export()).test);
MyClass.import(obj.export()).test = 2;
try {
window.postMessage(obj.export(), '*');
} catch(err) {
console.error(err);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With