Tari Ibaba

Tari Ibaba is a software developer with years of experience building websites and apps. He has written extensively on a wide range of programming topics and has created dozens of apps and open-source libraries.

How to Check if a Character Is a Letter in JavaScript

To check if a character is a letter in JavaScript, lowercase the character and compare it to the uppercased version, i.e., char.toLowerCase() !== char.toUpperCase(). If the result is false, the character is a letter. Otherwise, it isn’t.

For example:

JavaScript
function isCharLetter(char) { return char.toLowerCase() !== char.toUpperCase(); } console.log(isCharLetter('a')); // true console.log(isCharLetter('E')); // true console.log(isCharLetter('d')); // true console.log(isCharLetter('-')); // false console.log(isCharLetter('?')); // false

Note: This only works for most Latin, Greek, Armenian, and Cyrillic scripts. It won’t work for Chinese, Japanese, Arabic, Hebrew, or most other scripts.

One use for checking if a character is a letter is to validate forms. For example, if you have a form where a user needs to enter their name, you might want to ensure that only letters are entered, and not numbers or special characters.

We know that Latin letters have lowercase and uppercase forms that are different, so we take advantage of this using inequality.

JavaScript
console.log('z'.toLowerCase() !== 'z'.toUpperCase()); // true console.log('ж'.toLowerCase() !== 'ж'.toUpperCase()); // true

Non-letters, on the other hand, don’t have lowercase and uppercase forms; both toLowerCase() and toUpperCase() always give the same result.

JavaScript
console.log('.'.toLowerCase() === '.'.toUpperCase()); // true console.log('$'.toLowerCase() === '$'.toUpperCase()); // true console.log('='.toLowerCase() === '='.toUpperCase()); // true

Check if character is letter with regex

Alternatively, we can check if a character is a letter in JavaScript by calling the test() method on this regex: /^[a-z]$/i.

JavaScript
function isCharLetter(char) { return /^[a-z]$/i.test(char); } console.log(isCharLetter('g')); // true console.log(isCharLetter('Q')); // true console.log(isCharLetter('word')); // false console.log(isCharLetter('_')); // false console.log(isCharLetter('$')); // false

The RegExp test() method checks if a string matches the regular expression you specify. It returns true if there is a match, and false if there isn’t.

The forward slashes / / marks the start and end of the regular expression.

The ^ (caret) symbol indicates that the regex match must start from the beginning of the string. In this case, the letter must be the string’s first character.

The square brackets define a character set, which is a list of characters that can match any character at that position in the input string. In this case, [a-z] matches any single lowercase letter from a to z.

The $ symbol indicates that the regex pattern must be at the very end of the string. In this case, the letter must be the string’s last character. Combining ^ an $ in this way, ensures that the string is a single character.

The i flag lets us perform a case-insensitive search for the pattern. With i, we can omit the A-Z range that matches uppercase letters.

For a comprehensive guide to regular expression syntax, check out this cheat sheet from the MDN docs

Check if string contains letters

To instead check if a string contains any letters, we’ll use a different regex: /[a-z]/i

JavaScript
function containsLetter(str) { return /[a-z]/i.test(str); } console.log(containsLetter('code')); // true console.log(containsLetter('Q')); // true console.log(containsLetter('word')); // true console.log(containsLetter('_')); // false console.log(containsLetter('$')); // false

This is similar to the previous regex, except that we’ve removed the $ and ^ so that the search can occur at any point in the string, and a multi-character string containing at least one letter can be matched.

Check if string contains only letters

For checking if the string contains only letters, we’ll bring the $ and ^ back, and add a + before $:

JavaScript
function containsOnlyLetters(str) { return /^[a-z]+$/i.test(str); } console.log(containsOnlyLetters('code')); // true console.log(containsOnlyLetters('word')); // true console.log(containsOnlyLetters('coding_beauty')); // false console.log(containsOnlyLetters('s p a c e s')); // false console.log(containsOnlyLetters('8pm')); // false

With $ and ^ back again, the pattern is only matched if it’s the only pattern in the string. [a-z]+ only matches a consecutive series of letters. So altogether, the regex only matches strings that contain a continuous series of letters from the start to the end of the string.

Key takeaways

  • To check if a character is a letter, compare its lowercased and uppercased versions using char.toLowerCase() !== char.toUpperCase(). We can only regex by calling test() on /^[a-z]$/i.
  • To check if a string contains any letters, use the regex /[a-z]/i.
  • To check if a string contains only letters, use the regex /^[a-z]+$/i.

How to create a PDF from any HTML page or form using only JavaScript

With the jspdf library, we can easily convert any HTML page or form to a PDF:

For example:

JavaScript
import { jsPDF } from 'jspdf'; const pdfContentEl = document.getElementById('pdf-content'); const doc = new jsPDF(); await doc.html(pdfContentEl.innerHTML).save('test.pdf');

PDF is a popular file format we use to present and share documents with a fixed layout across different platforms and devices.

To start the conversion, we create a new jsPDF object with the constructor. Then we call the html() method, passing the element with the contents we want to be in the PDF. On the result, we call save(), passing our desired name of the output PDF file.

Let’s say we had HTML like this:

HTML
<div id="pdf-content"> <h1>Test</h1> <p>Here's what we're saving to PDF</p> </div> <button id="save-pdf">Save PDF</button>

with an output on the webpage like this:

The web page containing the PDF target HTML element.

When we click the “Save PDF” button, jsPDF will create a new PDF from the HTML element and download it as a file in the browser

Here’s what displays when we open the PDF:

The contents of the downloaded PDF.

Install jsPDF

To get started with the jsPDF library, we can install it from NPM with this command.

Shell
npm i jspdf

After the installation, we’ll be able to import it into a JavaScript file, like this:

JavaScript
import { jsPDF } from 'jspdf';

For this file to work in the HTML, we can use a module bundler like Parcel, which is what I use.

With Parcel, we can include the script in the HTML like this:

JavaScript
<script type="module" src="index.js"></script>

We can use modern tools like TypeScript and ES module imports in the script, and it will work just fine because of Parcel.

As far as we run the HTML with npx parcel my-file.html after installing Parcel with npm install parcel.

Shell
npm install parcel npx parcel my-file.html

Parcel makes the HTML available at localhost:1234, as you might have seen in the demo above.

Customize HTML to PDF conversion

The jsPDF constructor accepts an options object that customizes the PDF conversion process.

For example, the orientation option sets the orientation of the resulting PDF.

By default, it’s portrait, but we can set it to landscape.

Customize PDF orientation

JavaScript
const doc = new jsPDF({ orientation: 'landscape' });

Customize PDF unit and dimensions

With the unit and format options, we can set the unit and dimensions of each PDF page in the output file.

JavaScript
const doc = new jsPDF({ orientation: 'l', unit: 'in', format: [4, 2] });

Here we specify a landscape export that is 2 by 4 inches.

Convert HTML form to PDF

jsPDF also works with HTML elements whose appearance can change dynamically from user interaction, like form inputs.

HTML
<form id="form"> <input type="email" name="email" id="email" placeholder="Email" /> <br /> <input type="password" name="password" id="password" placeholder="Password" /> <br /><br /> <button type="submit">Submit</button> </form> <br /> <button id="save-pdf">Save PDF</button>
JavaScript
import { jsPDF } from 'jspdf'; const doc = new jsPDF(); const savePdf = document.getElementById('save-pdf'); const formEl = document.getElementById('form'); savePdf.addEventListener('click', async () => { await doc.html(formEl).save('test.pdf'); });

In the webpage, we’ve put in some test values in the two form inputs, to see that they display in the PDF output.

The PDF:

We can’t interact with the form inputs or button in the PDF file though.

Key takeaways

The jsPDF library provides a convenient way to convert HTML content, including forms, to PDF format. The entire process is pretty easy, as we can create a new jsPDF object, call the html() method to specify the content, and then use the save() method to generate the output file. Plus, we can customize the PDF output with options like orientation, unit, and format. Overall, using jsPDF simplifies creating PDF files from HTML content in our web apps.

How to Get the Length of a Map in JavaScript

To get the length of a map in JavaScript, we use it’s size property, e.g., console.log(map.size).

JavaScript
const map = new Map(); map.set('user1', 'John'); map.set('user2', 'Kate'); map.set('user3', 'Peter'); // 👇 Get length of map console.log(map.size); // 3

Map size, set(), and delete() methods

A Map object’s size property stores of key-value pairs in the object.

As the set() method adds elements and delete() removes them, the size property changes accordingly.

When we add a new element to a map with the set() method, the size property goes up by 1. In the same way, when we remove an element from the map with delete() the size goes down by 1.

JavaScript
const map = new Map(); map.set('user1', 'John'); console.log(map.size); // 1 map.set('user2', 'Kate'); console.log(map.size); // 2 map.delete('user1'); console.log(map.size); // 1

Map size vs Array length

Of course, a map and an array serve different purposes, but each has a property that gives the length of items it stores, length for arrays, and size for maps.

One key difference between the two is that you can change an array’s length property directly.

JavaScript
const arr = []; arr.push('Pat'); arr.push('Matt'); console.log(arr.length); // 2 // 👇 Array length changed arr.length = 1; console.log(arr.length); // 1

but you can’t do the same for maps:

JavaScript
const map = new Map(); map.set('user1', 'Pat'); map.set('user2', 'Matt'); console.log(map.size); // 2 map.size = 5; // 👇 length can't be modified directly console.log(map.size); // 2

You can only change size with methods like set() and delete(), as we saw earlier.

When you change Array length to a lesser value directly, elements are chopped off the end.

JavaScript
const arr = ['Pat', 'Matt']; // 👇 Length decreased directly arr.length = 1; // No more 'Matt' console.log(arr); // ['Pat']

On the other hand, when you directly change the Array length to a greater value, empty placeholder elements get added from the end of the array:

JavaScript
const arr = ['Pat', 'Matt']; // 👇 Length increase directly arr.length = 3; // Empty item added console.log(arr); // [ 'Pat', 'Matt', <1 empty item> ]

While this works, I would recommend Array splice() to remove elements from an array, so you have greater control over the deletion and can access the deleted elements.

With splice() you can set the start index for the deletion, the number of elements to delete, and new elements that should be inserted in their place.

JavaScript
const arr = ['Pat', 'Matt']; // Delete 1 element at index 1 (2nd element) const deleted = arr.splice(1, 1); console.log(deleted); // ['Matt'] const arr2 = ['Pat', 'Matt']; // Delete 1 element at index 1 (2nd element) and insert 'John' at index 1 const deleted2 = arr2.splice(1, 1, 'John'); console.log(deleted2); // ['Matt']

Clear Map with clear() method

What the Map clear() method does should be pretty obvious from its name; it clears the map of all its elements:

JavaScript
const map = new Map(); map.set('user1', 'John'); map.set('user2', 'Kate'); map.set('user3', 'Peter'); console.log(map.size); // 3 map.clear(); console.log(map.size); // 0

Key takeaways

  • To get the length of a map in JavaScript, use the size property of the map object.
  • size updates when you add or remove elements with set(), delete() or clear().
  • Unlike arrays, you can’t change the size of a map directly.

How to Easily Handle the onPaste Event in React

To handle the onPaste event on a React element, set its onPaste prop to an event handler. You can get the pasted text from the handler using event.clipboardData.getData('text').

For example:

JavaScript
import React, { useState } from 'react'; export default function App() { const [pasted, setPasted] = useState(''); const handlePaste = (event) => { setPasted(event.clipboardData.getData('text')); }; return ( <div> <input placeholder="Message" onPaste={handlePaste} type="text" id="message" /> <br /> You pasted: <b>{pasted}</b> </div> ); }
Handling the onPaste event on an element in React

The function (event listener) passed to the onPaste prop is called when the user pastes text into the input field.

The event object has various properties and methods used to get more info and take actions concerned with the event.

For the paste event, event has a clipboardData property that stores the data stored on the clipboard.

getData() gives us the data in the clipboard in a particular format. We pass 'text' as the first argument to get text data.

For the purposes of our example, we create a state that’ll be updated to the latest text data pasted in the input field. We display this text to the user.

Note: We used the useState hook to manage the state. This hook returns an array of two values, where the first is a variable that stores the state, and the second is a function that updates the state when it is called.

Handle onPaste event in entire window

To handle the paste event on the entire document window in React, set a paste event handler on the window object with addEventListener():

JavaScript
import React, { useState, useEffect } from 'react'; export default function App() { const [pasted, setPasted] = useState(''); useEffect(() => { const handlePaste = (event) => { setPasted(event.clipboardData.getData('text')); } window.addEventListener('paste', handlePaste) return () => { window.removeEventListener('paste', handlePaste) }; }) return ( <div> Pasted: <b>{pasted}</b> <br /> <input placeholder="Message" type="text" id="message" /> <br /> <input placeholder="Sender" type="text" id="sender" /> </div> ); }
Handling the onPaste event in the entire window in React

The addEventListener() method takes up to two arguments:

  1. type: a string representing the event type to listen for. 'paste' is for a paste event.
  2. listener: the function called when the event fires.

It also takes some optional arguments, which you can learn more about here.

We call addEventListener() in the useEffect hook to register the listener once the component renders as the page loads. We pass an empty dependencies array to useEffect so this registration happens only once. In the cleanup function, we call the removeEventListener() method to unregister the event listener and prevent a memory leak.

As we saw earlier, the event object has many methods and properties that let us get more info and take event-related actions.

For the paste event, event has a clipboardData property that contains the data stored on the clipboard.

The clipboard.getData() is the clipboard data in a specific format. Like before, we pass 'text' as the first argument to get text data.

Get clipboard data without paste

We may not want to wait for the user to do a paste before getting the clipboard data. In a case like this, the clipboard.readText() method from the navigator object helps:

JavaScript
import React, { useState } from 'react'; export default function App() { const [pasted, setPasted] = useState(''); const handlePaste = async (_event) => { const clipboardText = await navigator.clipboard.readText(); setPasted(clipboardText); } return ( <div> Pasted: <b>{pasted}</b><br /> <button onClick={handlePaste}>Paste</button> </div> ); }
Getting the clipboard data without pasting.

Here we wait for a click before getting the text in the clipboard.

readText() is an async method, so we await it in an async event handler to get the Promise‘s result.

Note

Before the browser can read clipboard data, it’ll show the user a dialog to grant permission first:

Browser shows popup to grant clipboard permissions.

Prevent onPaste event in React

Like for many other events, we can prevent the default UI action of the paste event with event.preventDefault() in the handler:

JavaScript
import React, { useState, useEffect } from 'react'; export default function App() { const [pasted, setPasted] = useState(''); useEffect(() => { const handlePaste = (event) => { // 👇 Prevent default paste UI action event.preventDefault(); setPasted(event.clipboardData.getData('text')); } window.addEventListener('paste', handlePaste) return () => { window.removeEventListener('paste', handlePaste) }; }) return ( <div> Pasted: <b>{pasted}</b> <br /> <input placeholder="Message" type="text" id="message" /> <br /> <input placeholder="Sender" type="text" id="sender" /> </div> ); }
Preventing the default paste action.

Key takeaways

To listen for pastes on an element and get clipboard text, we can use the event.clipboardData.getData() method. We can also handle pasted events on the entire window with window.addEventListener() and prevent the default UI action using event.preventDefault().

To get clipboard data without pasting, we use the clipboard.readText() method. These methods are useful for copying and pasting text between fields and preventing pasting behavior we don’t want.

How to Get the Current Page URL in React

We use the window.location.href property to get the current page URL in React.

For example:

JavaScript
import { useRef } from 'react'; export default function App() { const url = window.location.href; return ( <div> You are currently accessing <b>{url}</b> </div> ); }
Displaying the current URL in React.

We can use this same approach to get the current URL in Next.js

The window.location.href property returns a string that contains the entire page URL.

window.location contains other properties that give more information on the URL. Some of them are:

  • pathname: the path of the URL after the domain name and any optional port number.
  • protocol: the protocol scheme of the URL.
  • hostname: the hostname portion of the URL.

Here are some examples of using these properties to get various URL properties in addition to the full URL.

JavaScript
export default function App() { const url = window.location.href; const pathname = window.location.pathname; const protocol = window.location.protocol; const hostname = window.location.hostname; return ( <div> You are currently accessing <b>{url}</b><br /> Pathname: <b>{pathname}</b><br /> Protocol: <b>{protocol}</b><br /> Hostname: <b>{hostname}</b> </div> ); }
Displaying various URL properties.

Get current route in React Router

To get the current route in React Router, we use the useLocation() route.

For example:

JavaScript
import React from 'react'; import { Route, Link, Routes, useLocation } from 'react-router-dom'; function Home() { return <h2>Home</h2>; } function Products() { return <h2>About</h2>; } function Pricing() { return <h2>Pricing</h2>; } function Posts() { return <h2>Posts</h2>; } export default function App() { const location = useLocation(); const { hash, pathname, search } = location; return ( <div> <div> <Routes> <Route path="/products" element={<Products />} /> <Route path="/" element={<Home />} /> <Route path="/posts" element={<Posts />} /> <Route path="/#pricing" element={<Pricing />} /> </Routes> Pathname: <b>{pathname}</b><br /> Search params: <b>{search}</b><br /> Hash: <b>{hash}</b> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/products">Products</Link> </li> <li> <Link to="/posts?id=5">Posts</Link> </li> <li> <Link to="/#pricing">Pricing</Link> </li> </ul> </nav> </div> </div> ); }

useLocation() returns an object that contains information on the current page URL. Some of these properties are:

  • pathname: the part that comes after the domain name, e.g., /products.
  • search: the query string, e.g., ?id=5.
  • hash: the hash, e.g., #pricing.

Note

To get the full URL, we use location.href instead of useLocation().

JavaScript
const url = window.location.href;

Get dynamic route variable in React Router

To access the variables of a dynamic route directly in React Router, we use the useParams() hook.

For example:

JavaScript
import React from 'react'; import { Route, Routes, useParams } from 'react-router-dom'; function Posts() { const { id } = useParams(); return <h2>Settings for post {id} </h2>; } export default function App() { return ( <div> <div> <Routes> <Route path="/posts/:id" element={<Posts />} /> </Routes> </div> </div> ); }
Displaying the dynamic route variable.
Displaying the dynamic route variable.

The id variable corresponds to its placeholder value in the /posts/:id path. So as you saw in the example, the path /posts/5 will result in the id having a value of 5.

Get current route in Next.js app

To get the current route in a Next.js React app, we use the useRouter() hook:

The object useRouter() returns has a route property that is the current route in the Next.js app.

pages/posts.tsx
import Head from 'next/head'; import { useRouter } from 'next/router'; export default function Posts() { const posts = ['Post 1', 'Post 2', 'Post 3']; // 👇 Get route data const { route } = useRouter(); return ( <> <Head> <title>Next.js - Coding Beauty</title> <meta name="description" content="Generated by create next app" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.ico" /> </Head> <main> Route: <b>{router}</b> <br /> {posts.map((post) => ( <p>{post}</p> ))} </main> </> ); }
Displaying the current route in Next.js

We use useRouter() to get data and take actions related to the current app route.

Get current dynamic route data in Next.js

To get data passed to a dynamic route, we use the query property from the useRouter() object:

For instance, we could have a route /posts/5 corresponding to a dynamic route, /posts/:id where 5 is the passed value for id.

Here’s how we’ll access it in the Next.js file that handles requests to the dynamic route:

pages/posts/[id].tsx
import Head from 'next/head'; import { useRouter } from 'next/router'; export default function Posts() { const { query } = useRouter(); // 👇 Get id value from dynamic route const { id } = query; return ( <> <Head> <title>Next.js - Coding Beauty</title> <meta name="description" content="Generated by create next app" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.ico" /> </Head> <main> <h2> Post <b>{id}</b> </h2> </main> </> ); }
Displaying the data passed with the dynamic route in Next.js

For the dynamic route to work, the file structure in the pages folder has to be like this: /pages/[id].tsx. We name the file according to what property we’ll use to access the data from the query, and we wrap the name in square brackets.

We use useRouter() to get data and take actions related to the current app route.

Get query parameter data in Next.js

We can also access URL query parameters (i.e., ?key1=value1) using the query object:

JavaScript
import Head from 'next/head'; import { useRouter } from 'next/router'; export default function Posts() { const { query } = useRouter(); // 👇 Get source from query params const { id, source } = query; return ( <> <Head> <title>Next.js - Coding Beauty</title> <meta name="description" content="Generated by create next app" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.ico" /> </Head> <main> <h2> Post <b>{id}</b> </h2> <h3>You came from {source}!</h3> </main> </> ); }
Display data passed with URL query parameters in Next.js

Key takeaways

In React, we can use window.location.href to get the current page URL, and useLocation() to get information on the current route in React Router. For dynamic routes, useParams() accesses the values of a dynamic route directly.

For Next.js, we use the useRouter() hook to get info on the current route. From the object, it returns, route has the current route, and query gives us info on data passed to the app with the URL, like dynamic route and query parameter data.

[SOLVED] ERR_REQUIRE_ESM: require() of ES Modules is not supported

Are you experiencing the “require() of ES modules is not supported” error (ERR_REQUIRE_ESM) in Node.js? This error happens when you try to import a package that is an ES-only module with the CommonJS require() syntax:

The "require() of ES modules is not supported (ERR_REQUIRE_ESM)" error happening.
The “require() of ES modules is not supported” error occurred.

To fix it, use the ES module import syntax for the module, or install a previous version of the package that supports require().

Use ES module import syntax

The ES module system is now the standard method for bundling JavaScript code for sharing and reusing. An ES module can only be used by other ES modules.

So to import ES modules into our project, we first have to define the project as an ES module too. We do this by setting the type field in our package.json file to "module".

JSON
{ "type": "module", // other fields... }

Once we do this, we can use the ES import syntax for the module, like this:

JavaScript
import chalk from 'chalk';

Note

If we don’t make our project an ES module, you’ll get another error:

The "Cannot use import statement outside a module" error occurred.

So this step is required.

Use async import() function

Another way you can fix the “require() of ES modules is not supported” error is to use the async import function that allows you to dynamically load modules:

For example, here’s how we can do it for chalk:

JavaScript
(async () => { const chalk = (await import('chalk')).default; console.log(chalk.blue('Coding Beauty')); })();

And this works:

Install previous version of package

It’s possible that the package used to support require() but no longer does. Maybe a popular package like chalk or node-fetch. In that case, you can also fix “require() of ES modules is not supported” error in Node.js by installing one of those versions that support require().

As the ES module format become more popular and we saw all the benefits, many popular libraries on NPM started to drop support for CommonJS. Unlike CommonJS, ES modules provide more flexible and powerful module system features like asynchronous loading and tree shaking (removing unused code at build time).

Here are the versions you should install for various well-known NPM packages to use CommonJS and require():

The version of popular packages to install that last supported CommonJS.

node-fetch

Install node-fetch version 2:

JavaScript
npm install node-fetch@2 # Yarn yarn add node-fetch@2

Note: Specify only the major version (use 2, not 2.x.x) so you can get all the latest important bug fixes published for version 2.

got

Install got version 11:

JavaScript
npm install got@11 # Yarn yarn add got@11

Note: Unlike node-fetch, got v11 is not being maintained anymore.

chalk

Install chalk version 4:

JavaScript
npm install chalk@4 # Yarn yarn add got@4

nanoid

Install nanoid version 3:

JavaScript
npm install nanoid@3 # Yarn yarn add nanoid@3

Others

If the package isn’t among the ones above, try browsing through its homepage or NPM package page to find any notices of dropped CommonJS support.

Conclusion

The “require() of ES modules is not supported” error occurs in Node.js when we attempt to use CommonJS require() on a package that is now an ES module. To fix it, we can use the ES module import syntax for the module, use the async import() function, or install a previous version of the package that supports require(). The ES module system is better as it provides powerful features like asynchronous loading and tree shaking, making it the preferred method for bundling JavaScript code.

How to Get the Sum of an Array in JavaScript

To get the sum of an array in JavaScript, call the reduce() method on the array, with two arguments: a callback that takes two arguments and returns their sum, and 0.

For example:

JavaScript
const sum = (arr) => arr.reduce((a, b) => a + b, 0); const arr = [1, 2, 3, 4, 5] const result = sum(arr); console.log(arr); // 15

When we call reduce() method on arr, it loops through the array and adds each element to a sum value When the loop is done, this value will hold the total sum of the array, and reduce() will return it.

The callback argument is called on each array element and takes two arguments, a and b. a represents the total sum value so far and b represents the current element in the iteration. The callback simply adds the current element to the total sum value so far and returns it.

The second argument reduce() takes is an initial value of the total sum. We set it to 0 in this case, but this is the default value anyway, so we can leave it out:

JavaScript
// No need for second argument when it's zero const sum = (arr) => arr.reduce((a, b) => a + b); const arr = [1, 2, 3, 4, 5] const result = sum(arr); console.log(arr); // 15

Get sum of array with for..of loop

Alternatively, we can get the sum of an array in JavaScript using a for..of loop and taking these steps:

  1. Create a variable to store the sum.
  2. Loop over the array.
  3. Add each element to the sum.

For example:

JavaScript
function sum(arr) { let result = 0; for (const item of arr) { result += item; } return result; } const arr = [1, 2, 3, 4, 5] const result = sum(arr); console.log(arr); // 15

Throughout the loop, item will hold the value of each array element, so we add its value to sum in each iteration.

Get sum of numbers with forEach() method

Of course, wherever we can use for..of we can use forEach():

JavaScript
function sum(arr) { let result = 0; arr.forEach(item => { result += item; }); return result; } const arr = [1, 2, 3, 4, 5] const result = sum(arr); console.log(result); // 15

The forEach() loops over each element in the arr array. It takes a callback function as its argument that is called on each element of the array. Like we did with for..of, the callback function simply adds the current element to the result variable.

Get sum of numbers with for loop

And forEach() or for...of can equally be replaced with the traditional for loop:

JavaScript
function sum(arr) { let result = 0; for (let i = 0; i < arr.length; i++) { result += arr[i]; } return result; } const arr = [1, 2, 3, 4, 5] const result = sum(arr); console.log(result); // 15

How do they compare in speed?

We performed a test to compare the running times of the four different methods above for summing an array in JavaScript: the for loop, forEach(), for...of loop, and reduce() methods.

We tested each method three times and noted how long it took to complete each test. Then we averaged the results to get a more accurate representation of the execution times.

Each test case involved summing an array of the first 1 million positive integers.

Speed comparison of the different methods of getting the sum an array in JavaScript.
Speed comparison of the different methods.

The for loop method was the fastest, taking only an average of 4.530 ms to complete. The forEach() method was the slowest, with an average execution time of 31.123 ms. The for...of loop and reduce() methods were relatively close in execution time, with average execution times of 22.940 ms and 21.463 ms, respectively.

Overall, the for loop method was the most efficient for summing an array in JavaScript, while the forEach() method was the least efficient. Still, the best method to use depends on your specific use case and the array’s size.

When dealing with small arrays, the difference in performance between different methods for summing the array may not be noticeable. But as the size of the array increases, this difference can become more significant and can affect the code’s overall running time.

So for very large arrays, it’s important that we choose the most efficient method for computing the sum to avoid slow execution times. By choosing the most efficient method, we’ll make sure that our code runs as quickly and efficiently as possible, even when dealing with huge amounts of data.

How to Fix the “structuredClone is not defined” Error in Node.js

The “structuredClone is not defined” error occurs when you try to use the structuredClone()/ method in JavaScript, but it’s not defined.

The "structuredClone is not defined" error occuring in a terminal.
The “structuredClone is not defined” error occuring in a terminal.

To fix it, install Node.js 17 or a newer version. Once you’ve updated Node.js, you can use structuredClone() to clone objects with all their properties and methods.

What causes the “structuredClone is not defined” error?

If you try to use the structuredClone() method in a script that’s running with a Node.js version lower than 17, you will encounter this error.

The structuredClone() method is used to create a deep copy of an object. It’s a built-in function in JavaScript and is used to clone an object with all its properties and methods.

But when the structuredClone() method is not defined, it means that the server environment doesn’t recognize the function and cannot perform the action.

Fix: update Node.js

To fix the “structuredClone is not defined” error in JavaScript, you need to install Node.js 17 or a newer version. If you’re using an older version of Node.js, it will throw an error when you try to use structuredClone().

Install from website

To download Node.js, visit the official website and opt for the LTS version, as it offers superior stability. As of the time of writing this article, the most recent LTS release of Node.js is v18.15.0.

The Node.js download page on the official website.
The Node.js download page on the official website.

Install with Chocolatey

If you’re using Chocolatey, Node.js is available as the nodejs package, meaning you can easily install it in a terminal using the following command.

Shell
# Use current LTS version choco install nodejs --version=18.5.0

After installing, you can use the structuredClone method to clone an object:

JavaScript
const obj = { name: 'Mike', friends: [{ name: 'Sam' }] }; const clonedObj = structuredClone(obj); console.log(obj.name === clonedObj); // false console.log(obj.friends === clonedObj.friends); // false

Key takeaways

If you get the “structuredClone is not defined” error when using the structuredClone() method in JavaScript, it means that the method is unavailable. To fix the problem, update your Node.js to a version newer than 17. You can get the latest version from the official Node.js website or install the nodejs package using Chocholatey.

How to Simulate a KeyPress in JavaScript

To simulate a keypress in JavaScript:

  1. Get the text field element with a method like document.querySelector().
  2. Create a new KeyboardEvent object.
  3. Call the dispatchEvent() method on the text field, with the KeyboardEvent object.

i.e.:

JavaScript
function simulateKeyPress(key) { const event = new KeyboardEvent('keydown', { key }); textField.dispatchEvent(event); }

“Text field” here might be an input element, textarea element, or even a content editable div.

A KeyboardEvent object describes a user’s interaction with the keyboard. Its constructor takes two arguments:

  • type – a string with the name of the event. We pass 'keydown' to indicate that it’s the event of a key press.
  • options – an object used to set various properties of the event. We used the object’s key to set the keyboard key name associated with our key press.

For example:

HTML
<input type="text" name="text-field" id="text-field" placeholder="Text field" /> <br /> Key presses: <span id="key-presses">0</span> <br /><br /> <button id="simulate">Simulate</button>
JavaScript
const textField = document.querySelector('#text-field'); const keyPresses = document.getElementById('key-presses'); const keyPressed = document.getElementById('key-pressed'); const simulate = document.getElementById('simulate'); // Set 'keydown' event listener, for testing purposes let keyPressCount = 0; textField.addEventListener('keydown', (event) => { keyPressCount++; keyPresses.textContent = keyPressCount; keyPressed.textContent = event.key; }); simulate.addEventListener('click', () => { simulateKeyPress('a'); }); function simulateKeyPress(key) { const event = new KeyboardEvent('keydown', { key }); textField.dispatchEvent(event); }

First, we use selector methods like document.querySelector() and document.getElementById() to get an object representing the various elements to be used in the JavaScript code.

Then, we call the addEventListener() method on the text field object to set an event listener for the keydown event. When the user types a key or input is simulated from a script, the event listener will be fired, incrementing the key press count and displaying the most recently pressed key.

We also call the addEventListener() method on the simulate button object for the click event to simulate the key press when the user clicks the button.

Simulating a keypress fires the key event.
Simulating a keypress fires the key event.

Notice that the key is not entered in the text field. This is because of the isTrusted property, which indicates whether a user action or script generated an event. When isTrusted is false, the event is not considered trusted and does not reflect visually in the text field. Browsers do this for security reasons.

JavaScript
const event = new KeyboardEvent('keydown', { key, ctrlKey: true }); console.log(event.isTrusted); // false

isTrusted is a readonly property and will only be true when an actual user’s action caused the event; in this case: typing on the keyboard.

Insert value into input field or textarea

If you want to enter a key into the text field programmatically, you’ll have to use other approaches. For input and textarea elements, here’s a method you can use:

JavaScript
function insertTextAtCursor(element, text) { element.focus(); const startPos = element.selectionStart; const endPos = element.selectionEnd; element.value = element.value.substring(0, startPos) + text + element.value.substring(endPos, element.value.length); element.selectionStart = element.selectionEnd = startPos + text.length; }

This function takes the text field element and some text as arguments and inserts the text into the text field, replacing any highlighted text before the insertion.

You can also use the insert-text-at-cursor NPM package to insert text into an input field or textarea. Its default export function works like the one above.

JavaScript
import insertTextAtCursor from 'insert-text-at-cursor';

Either function can be called like this:

JavaScript
insertTextAtCursor(textField, 'Coding Beauty');

Simulate keypress in input field with key modifier

Sometimes, you might want to simulate a key combination that includes the modifier keys, e.g., Ctrl + A, Ctrl + Shift + C, etc. There are option properties you can set to do this.

For instance, setting the ctrlKey property to true simulates the Ctrl + {key} combination, where {key} is the value assigned to the key property.

JavaScript
// Ctrl + c, Ctrl + o, Ctrl + d, Ctrl + e const keysToSend = 'code'; let keyIndex = 0; simulate.addEventListener('click', () => { simulateKeyPress(keysToSend.at(keyIndex++) || keysToSend.at(-1)); }); function simulateKeyPress(key) { const event = new KeyboardEvent('keydown', { key, ctrlKey: true }); textField.dispatchEvent(event); }
Simulating various keys with the Ctrl modifier.
Simulating various key combinations with the Ctrl modifier.

Some other important key modifier option properties are:

  • altKey: adds the Alt key to the key combination, e.g., Alt + Z, Ctrl + Alt + N, etc.
  • ctrlKey: adds the Ctrl key to the key combination, e.g., Ctrl + A, Ctrl + Shift + T, etc.
  • shiftKey: adds the Shift key to the key combination.
  • metaKey: adds the ⌘ key on MacOS and the Windows key on Windows to the key combination.

Key takeaways

We can easily simulate keypresses in JavaScript on a text field by calling the dispatchEvent() method on the element object, passing a custom-created KeyboardEvent object as an argument. While this will trigger the appropriate key events set on the element, it would not visually reflect on the text field since programmatically created events are not trusted for security reasons.

How to Set Focus on the Next Form Input With JavaScript

To move focus from one input to the next one in a form:

  1. Get a list of all the input elements in the form.
  2. Get the index of the input element in the list that has focus.
  3. Get the index of the next input element in the list.
  4. Focus on it.
JavaScript
function focusNext() { const currInput = document.activeElement; const currInputIndex = inputs.indexOf(currInput); const nextinputIndex = (currInputIndex + 1) % inputs.length; const input = inputs[nextinputIndex]; input.focus(); }

For example:

HTML
<form class="form"> <input type="number" name="num1" id="num1" placeholder="1st Number" maxlength="2" /> <input type="number" name="num2" id="num2" placeholder="2nd Number" maxlength="3" /> <input type="number" name="num3" placeholder="3rd Number" id="num3" maxlength="4" /> <button type="submit" id="submit-btn">Submit</button> </form>
CSS
.form { display: flex; flex-direction: column; width: 200px; } .form input:not(:first-of-type) { margin-top: 10px; } .form #submit-btn { margin-top: 20px; }
JavaScript
// Convert NodeList to Array with slice() const inputs = Array.prototype.slice.call( document.querySelectorAll('.form input') ); inputs.forEach((input) => { input.addEventListener('keydown', (event) => { const num = Number(event.key); if (num && num >= 0 && num <= 9) { // Only allow numbers if (input.value.length >= input.maxLength) { event.preventDefault(); focusNext(); } } }); }); function focusNext() { const currInput = document.activeElement; const currInputIndex = inputs.indexOf(currInput); const nextinputIndex = (currInputIndex + 1) % inputs.length; const input = inputs[nextinputIndex]; input.focus(); }
The next input gains focus when the input limit is reached.
The next input gains focus when the input limit is reached.

We use the document.querySelectorAll() method to obtain a collection of all the input elements in the form. This method in JavaScript allows you to find all the elements on a web page that match a certain pattern or characteristic, such as all elements with a particular class name or tag name.

We use the forEach() method to iterate over the array of input elements we obtained using document.querySelectorAll(). For each input element, we add an event listener to listen for the keydown event.

When a key is pressed down, we check if the key pressed is a number between 0 and 9. If it is, we check if the length of the input’s value is equal to its maxLength attribute. If it is, we prevent the default action of the event and call the focusNext() function to move the focus to the next input element.

The forEach() method is a higher-order function in JavaScript that allows you to run a function on each element of an array.

Tip: A higher-order function is a function that can take in functions as arguments and/or return a function.

In the focusNext() function, we first get the currently focused input element using document.activeElement. We then get the index of this input element in the inputs array we created earlier using inputs.indexOf(currInput).

We then calculate the index of the next input element in the array using (currInputIndex + 1) % inputs.length, where % is the modulo operator. This ensures that if the currently focused input element is the last one in the array, we wrap around to the first input element.

Finally, we get a reference to the next input element using inputs[nextinputIndex] and call the focus() method on it to move the focus to the next input element.

Set focus on next input on enter

Sometimes, we want to move the focus to the next input element when the user presses the Enter key instead of waiting for the input’s maxLength to be reached. To do this, we can add an event listener to listen for the keydown event on each input element. When the Enter key is pressed, we prevent the default action of the event and call the focusNext() function to move the focus to the next input element.

JavaScript
inputs.forEach((input) => { input.addEventListener('keydown', (event) => { if (event.key === 'Enter') { event.preventDefault(); focusNext(); } }); });

Now, when the user presses the Enter key, the focus will move to the next input element. This can be especially useful in forms where the user needs to quickly move through a series of inputs without having to manually click on each one.