1

Would the following code be a terrible anti pattern, and is there a better way to observe event responses. I specifically need to see the event response asynchronously

component.dispatchEvent(new CustomEvent('some-event', { detail: (arg) => { 
   // do something with arg 
}}))

window.addEventListener('some-event', async (event) => {
  // do something asynchronously and generate result data 

  event.detail(result)
})
rubixibuc
  • 7,111
  • 18
  • 59
  • 98
  • Uncommon? Yes. Terrible? Depends on the use case. What does the callback do concretely, what does it wait for? Ask yourself: what happens if nobody subscribed to the event, and if the callback is never called? What happens if there are multiple subscribers, and the callback is called multiple times? Depending on the answers, I would suggest to either a) not use an event mechanism at all, but call the data-generating function directly and wait for the promise it returns or b) use a `some-response-event` fired when the result data is generated, and listened for by the component. – Bergi Jul 26 '20 at 19:32
  • So I trigger a save entity event that the parent receives and either success or fails. Depending on the asynchronous response I will close a form modal or keep it open to make corrections. Your idea of some-response-event is interesting. Maybe I can dispatch another event on the event.target? would that be cleaner? – rubixibuc Jul 26 '20 at 19:38
  • Yes, that would be cleaner, but given that you expect only a single response I would probably not use events at all. Can you not pass the promise-returning `onSave` handler as an argument when constructing the component? Alternatively emit the `save` event, and allow the parent to call the `component.close()` method directly, if that's all what the callback would do. – Bergi Jul 26 '20 at 19:45
  • 1
    So I have a tree of native web components, and the save form is several layers deep in the tree. I pass in the data from the top of the tree. The tree is generically created off of entity metadata. The form triggers a save event that the top element handles. The open and close functionality is not controlled from the top, as there are several entities that have forms that could be open. I was using events to try and keep it loosely coupled – rubixibuc Jul 26 '20 at 19:49
  • "*The open and close functionality is not controlled from the top*" - and yet the top *does* control the saving functionality that might fail or not, causing the modal to close or show an error message. So I just would suggest that you don't pass a single callback along with your event, but you offer a method to call (`afterSave(arg)` or whatever) and your `onSave` handler can then use `event.target.afterSave(result)`. Thinking of it as a method also ensures that you design it to be called at any point with any state, always doing something reasonable, instead of depending on assumptions. – Bergi Jul 26 '20 at 19:59
  • would this be terrible? event.target.dispatchEvent('some-event-indicating-success'). This fits better with the web component framework I'm using and code I have. It's actually the direct parent of the target that controls opening and closing – rubixibuc Jul 26 '20 at 20:08
  • Yes, that would be fine as well - using events or method calls for message passing is very similar (return values and bubbling are what makes one or the other more appropriate). If it works for you, go ahead. – Bergi Jul 26 '20 at 20:19

0 Answers0