Copy and paste in JavaScript

Sometimes, it’s helpful to copy and paste some text programmatically. There are different options in Javascript, and the only one that works consistently is the following:

You can see an example of the above code in action on Stackblitz here. The only caveat is that such code can be triggered from an event listener, such as onClick.

A newer API is emerging but isn’t fully supported anywhere, and Firefox support is significantly lacking, so I wouldn’t recommend it. The main problem with that new approach is that it requires the user’s permission, and there’s currently no way to ask for it. The Permissions API seems to be a bit inconsistent and lacking at this point:

It’s a shame because that new API would allow copying custom content into the clipboard, not just the current user’s selection.

By the way, a quick reminder to tune in for the Angular live event today on Youtube.

Everything you need to know about Arrow Functions

Arrow functions have become the standard syntax in modern JavaScript. They offer a concise way to write functions, making your code lighter and more readable. Let’s explore arrow functions and their various syntax options with code examples.

Basic syntax

Two things to note:

  • Parentheses are required when using multiple function parameters.
  • In a one-liner arrow function, the result of the expression is automatically returned.

Zero or One Parameter

If your function has only one parameter, parentheses become optional. If there’s no parameter, then you do need the parentheses:

Multiple instructions

If your function has multiple lines of code, then you need curly braces and a return statement:

Why use arrow functions?

Aside from the syntax improvements described above, arrow functions are helpful in classes because they preserve the context of this. By default, in JavaScript, this means “the current function,” not “the current class instance.” Arrow functions fix that scope for us:

Backticks, double quotes, and single quotes

When working with strings in Javascript, we have three options: Backticks, double quotes, and single quotes. Today, let’s look at when to use each of these and the pros and cons of each approach.

Single-quotes

Single quotes are the least exciting option because they have primarily cons:

Double-quotes

Double quotes get the job done most of the time but don’t shine when building template strings with multiple lines:

Backticks

Backticks are superior most of the time because they were designed to make template strings easy:

It’s been proven that there are no differences in performance when using backticks in modern Javascript. It’s also important to remember that with Angular, our TypeScript compiler will compile those backticks into double quotes if our compiler is set to any version of Javascript before ES6, so you don’t have to worry about browser compatibility either. All modern browsers support template literals with backticks.

JavaScript rest operator

This is the final post in our JavaScript series on destructuring. Let’s focus on the rest operator, which materializes with three little dots ... as follows:

One way to put it is that the rest operator means “everything else goes into a new array.”

This syntax also works with objects, with the “rest of the properties going into a new object”:

The rest operator can also be used in a function to catch several parameters in an array:

Array destructuring with JavaScript

In our last post, we saw how to implement object destructuring. A similar feature is available for arrays and replaces the following syntax:

With destructuring, we can simplify that code into:

The only difference with object destructuring is the usage of square brackets [] instead of curly ones {}. Default values are supported, too:

And if you want to ignore one or more items in the array, you can leave blank spaces instead of variable names:

You can find more examples in the MDN web docs here.

Object destructuring with JavaScript

Here is something I see very often while reviewing Angular code for the Angular certification program:

While the above code works, it is very lengthy and repetitive. It also increases your code base’s size, negatively impacting performance. Instead, we can use a modern JavaScript syntax introduced with ES6/ES2015 called object destructuring:

The above line of code does the same as the three previous lines. What if we want the local variable to have a different name than the original property? Say we want to name our new variable homeAddress instead of address. We can do it like this:

What if we want those variables to have a default value in case they are not defined in this.user? We can do that too:

Now you know everything you need about object destructuring.

Notifications from LocalStorage with Signals

Yesterday, we saw that LocalStorage can be used as a persistent cache to store our data in the browser. Earlier, we covered that services are a cache of their own but have one instance per app/browser tab, which means that applications opened in multiple tabs can have an inconsistent state since they each have their own “singleton” services.

LocalStorage can be used to share data between multiple tabs that render the same application. Even better, there is a storage event that can be listened to to know when another tab updated LocalStorage:

Using the Rxjs fromEvent function, we can turn the above event listener into an Observable:

And if we’re using Angular 16+, we can turn the above Observable into a Signal with one more function:

The above Signal could be used in a service to synchronize data between tabs. Spying on that Signal to see what’s going on in it is as easy as registering a side-effect on it using the effect function:

You can see that code example on Stackblitz.

LocalStorage and SessionStorage

Last week, we covered the lifecycle of Angular applications and how services can be used as a cache for our data.

I mentioned that Angular apps are independent applications running in a browser tab and that closing such a tab “kills” the application and frees the memory used by our app – thus losing any data stored in our services. Using the browser’s refresh button would also clear everything – similar to a reboot of the application.

If we want a more persistent cache, we can use the localStorage API from Javascript. Learning that API takes five seconds:

The above code stores the string “Tom” in the browser localStorage under the key “myCat”. To read that value, later on, all we need is the following:

And that’s it! Such storage will remain in place if the user closes your app’s tab or even closes the browser and shuts down their computer. Your data stays in the browser storage if the user does not clear the browser’s cache.

Also, such data is stored based on the domain on your web app, so other websites cannot read your storage values, and you can’t access values from other websites either.

One last tip: To store objects or arrays in localStorage, we have to turn them into strings, which means we usually do the following:

And to read that object from localStorage:

Note that sessionStorage has the same API as localStorage, but follows different rules and has a shorter life span:

  • A page session lasts as long as the tab or the browser is open and survives over page reloads and restores.
  • Opening a page in a new tab or window creates a new session with the value of the top-level browsing context.
  • Opening multiple tabs/windows with the same URL creates sessionStorage for each tab/window.
  • Duplicating a tab copies the tab’s sessionStorage into the new tab.
  • Closing a tab/window ends the session and clears objects in sessionStorage.

How to create a copy of anything in Javascript?

Modern Javascript developers are used to the following syntax to create a copy of an object:

let copy = {...object};Code language: JavaScript (javascript)

While this approach works fine, it creates a shallow copy of the object, not a fully-fledged clone that also duplicates nested objects and arrays.

As a result, Javascript developers have learned another trick to perform a deep copy:

let copy = JSON.parse(JSON.stringify(object));Code language: JavaScript (javascript)

The idea of this approach is to turn an object into a JSON string before parsing that string back into a brand-new object. It works, but it’s not elegant and looks like a hack.

As a result, a better approach has been added to the Javascript language: the structuredClone function. It’s a syntax improvement that creates deep clones efficiently:

let copy = structuredClone(object);Code language: JavaScript (javascript)

The function is supported across all recent major browsers as shown on Can I use:

If you need to support another browser, there is a polyfill implementation in core.js.

The debugger keyword

Yesterday, we covered how to use the JSON pipe with a <pre> tag to debug JSON data on a web page.

Today, I want to cover one more debugging technique that is another time saver: The debugger keyword.

Whenever you want to add a breakpoint in your web application, add the Javascript instruction:

debugger;Code language: JavaScript (javascript)

Then open the dev tools in your browser and navigate to your application URL. Whenever Javascript hits that debugger statement, the runtime will stop on that breakpoint, allowing you to debug your code:

Once the browser is paused on that breakpoint, you can add other breakpoints by clicking on the line numbers in the browser dev tools, just like regular debuggers work.

Two important things to note:

  1. The breakpoint works only when the dev tools are open
  2. Don’t forget to remove the debugger statement once you’re done debugging. You probably don’t want to ship that one to production.