dispatchEvent(new Proxy(event, {}) does not work
Asked Answered
N

1

6

I'm working on an app which uses events. The modules of the app execute in separate containers and I thought about using Proxy to tame the events that are fired. However, I cannot seem to be able to make dispatchEvent accept an event that has been proxied.

The following fails:

let event = new CustomEvent('my event');
let eventProxy = new Proxy(event, {});
let eventTarget = document.createElement('div');

try {
    eventTarget.dispatchEvent(eventProxy); // VM134:4 Uncaught TypeError: Failed to execute 'dispatchEvent' on 'EventTarget': parameter 1 is not of type 'Event'
} catch(error) {
    console.log(error.message);
}

Anyone has any ideas how dispatchEvent can be made to accept proxies?

Nadenenader answered 6/9, 2018 at 20:19 Comment(7)
What do you mean by "tame the events that are fired"?Pecan
restrict/filter property values depending of the container in which the event is being caught.Nadenenader
new Proxy(event, {}) does not create a fully transparent replacement object. You need a lot more to handle that unfortunately.Tailpiece
@Tailpiece what more?Perianth
@Perianth In the generic case, you need a everything that crosses a proxy boundary to be wrapped, so you should never return any object from a proxy handler unless it is also wrapped in a Proxy. This is generally referred to as a "membrane": tvcutsem.github.io/js-membranes #43178355Tailpiece
@Tailpiece this membrane won't make dispatchEvent() accept proxied objectPerianth
@Perianth If you have a membrane then every access should go through the membrane, so it would be the membrane's job to unwrap the proxy and pass the underlying event object as the argument for dispatchEvent since dispatchEvent is also something from outside the membrane. It's very complicated, which is why I'd generally say using a Proxy as a generic "programmable object" is a mistake.Tailpiece
H
0

Could be an old question, but It may help someone, because I didn't find similar Q&As about this.

As pointed in the comments:

Proxy will not create a fully transparent replacement object.

You can also log out eventProxy and see that most of the properties are unaccusable.

My suggestion is wrapping your Event with an object that has a function that returns the event. (for multiple events, you can even use that object for a gateway to all events).

Then, dispatch the event that returns by calling that function.

Now, when you proxy the new object, you can override the get in the handler to log the call.

let event = new CustomEvent('my event');
let eventWrapper = { getEvent: ()=> event };
let handler = {
get: function(target, thisArg, argumentsList) {
    console.log('Logged!');
    return Reflect.get(...arguments)
  }
}
let eventProxy = new Proxy(eventWrapper, handler);
let eventTarget = document.createElement('div');

try {
    eventTarget.dispatchEvent(eventProxy.getEvent());
    console.log("Done!")
} catch(error) {
    console.log(error.message);
}
Hercules answered 2/1, 2021 at 2:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.