I'm Matt - You're here for my blog!

Month: January 2023

TIL: Browser window/tab/frame/iframe intercommunication via BroadcastChannel Web API

I was today years old when I learned of the BroadcastChannel Web API, which facilitates intercommunication between windows, tabs, frames and iframes on the same domain (thanks to Cory House on Twitter).

At a glance, the API is surprisingly simple, so I figured why not give it a spin.

After consulting the ever-valuable MDN Web Docs on the topic, I had a BroadcastChannel spun up in a matter of seconds – here’s the overview and demonstration of it in action.

To setup my playground, I simply opened up a new Chrome window – and then 2 tabs, which I pointed to my blog here. At this point, all that’s left to be done is to new up an instance of BroadcastChannel in both tabs, setup an onmessage event listener in the receiver tab, and then to broadcast a message from the sender tab.

Here we have our ‘sender’ tab in tab 1 – where we’ve instantiated a new BroadcastChannel, setup an event listener, and then posted a new message.
Note: We could have skipped setting up the listener here, but I wanted to demonstrate that the sending tab doesn’t display the posted message.
Here we have our ‘reciever’ tab in tab 2 – where we’ve instantiated a new BroadcastChannel and setup an event listener. As we can see in the last visible debugger frame, we recieved our ‘WOW!’ message from tab 1.
Note: The ‘WOW!’ message was sent from tab 1 after setting up the listener in tab 2 – previously posted messages from other tabs are not recieved in tabs/windows/frames instantiated after the message has been broadcast.

Cool, cool, cool. So pretty simple – here’s the explicit flow of this experiment in case it’s not clear from the screenshot captions:

  • Open 2 tabs on the same domain – ‘https://blog.immatt.com’ in my example
  • In tab 1, create a new BroadcastChannel instance via “new BroadcastChannel(‘channel-name’);”
  • In tab 2, also create a new BroadcastChannel instance for the same channel name – e.g. “new BroadcastChannel(‘channel-name’);”
  • In tab 2, setup an event listener for the ‘onmessage’ event exposed on our BroadcastChannel instance
  • Back in tab 1, broadcast a message to all subscribers of our channel by using the ‘postMessage()’ function exposed on the ‘sender’ instance of BroadcastChannel
  • Check back in tab 2 to see our super awesome message!

Here’s the expanded console object of the recieved message for a better look at the MessageEvent payload:

Also worth mentioning, browser compatibility is pretty solid – with it having landed in most major browsers around 2015/2016 (except Edge, which was 2020).

Anywhos. There you have it… Inter-tab/window/frame/iframe communications via the BroadcastChannel Web API!

Happy Coding!
-Matt

ES/TC39 Proposals – Change Array by copy (Stage 3) – Immutable Array Operations

As a follow up to my last post, I’ve decided to dig in a little more to some of the upcoming TC39 proposals. The proposal that we’re reviewing today provides a few new ways to work with Arrays in an immutable way – a proposal titled “Change Array by copy”.

As the title “Change Array by copy” suggests, the new methods covered by the proposal provide Array functions which allow working with arrays in an immutable fashion (with the assumed intent of reducing side effects often associated with mutable objects, which are capable of being directly changed).

Included under the proposal are:

  • Array.prototype.toSorted()
  • Array.prototype.toReversed()
  • Array.prototype.toSpliced()
  • Array.prototype.with()

You can check out the collaborative view of this proposal on GitHub.

Let’s dive in!

Similarly to Array.prototype.sort(), Array.prototype.toSorted() exposes a helper function capable of sorting members of an array sequentially. Unlike to Array.protptype.sort(), Array.prototype.toSorted() returns a new array, by copy, leaving the original array untouched. To see this in action, see the following example:

Array.prototype.sort() vs Array.prototype.toSorted() – As expected, arr1 is changed, while arr2 is not.

Up next, we have Array.prototype.toReversed() – essentially, the immutable form of Array.prototype.reverse(). Just as reverse() reverses the member order of the array, so to does toReversed() – but, again, without modifying the source array being operated on/against.

Array.prototype.reverse() vs Array.prototype.toReversed() – As expected, arr1 is changed, while arr2 is not.

Last in our one-to-one function comparison is Array.prototype.toSpliced() – similar to the long standing and familiar Array.prototype.splice(), which is used to remove or replace elements within an array. As we can see in the following example, we’re capable of removing and replacing array elements with both splice() and toSpliced() – with the distinction that toSpliced() doesn’t modify the original array, and instead provides us a new, updated one via copy.

Array.prototype.splice() vs Array.prototype.toSpliced() – As expected, arr1 is changed, while arr2 is not.

And finally, we have Array.prototype.with(). Unlike the previously discussed parts of the proposal, with() doesn’t really have a similarly named existing function – though we’re all likely familiar with the logic in play. When working with an array, it’s often common practice to reassign a value within an array by assigning a new value using the target’s zero-based index – with() exposes exactly this functionality, via a function call. See the following example to see Array.prototype.with() in play:

Array index-based assignment vs Array.prototype.with() – as expected, arr1 is changed, while arr2 is not.

As you may have noticed in the above (and in case you did not) we’re once again using the core-js library to play with these new, not-yet-spec, JavaScript proposals – so check it out, and perhaps give it a spin!

Anywhos… I’m really enjoying having the opportunity to look forward and actually play with new stuff in the works for JavaScript. Yay, funemployment! That said, if you or someone you know is seeking a developer with well over a decade of full stack experience, including large enterprise engineering and architecture, please do reach out via matt@immmatt.com or ping me on Twitter @mattezell!

Happy Coding!
-Matt

© 2024 blog.immatt

Theme by Anders NorenUp ↑