javascript

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.

Get Started with MutationObserver: Everything You Need to Know

The MutationObserver API allows tracking changes to the DOM tree, including when elements are added, removed, modified, or have an attribute changed. It can also track changes to an element’s contents or styles, such as the addition or deletion of text or when a style property is modified.

We’ll look at how to use the Mutation API in this article and real-world use cases to see its importance.

Mutation Observer in action

Let’s look at the Mutation Observer API in action right away:

JavaScript
// Usage const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { const el = mutation.target; if (el.textContent === 'Hello!') { el.textContent = 'Welcome!'; } } }); const textEl = document.getElementById('info'); observer.observe(textEl, { childList: true }); // Test const changeText = document.getElementById('change-text'); changeText.addEventListener('click', () => { textEl.textContent = 'Hello!'; });
The displayed text is changed by Mutation Observer.
The displayed text is changed by Mutation Observer.

Create a Mutation Observer

We create a Mutation Observer using the MutationObserver() constructor. The constructor accepts a callback that will be called when a mutation is detected on an element.

The callback is passed an array of MutationRecord objects, each containing information about the particular mutation that just occurred.

JavaScript
const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { // Process mutations... } });

Two essential properties that a MutationRecord object has are the target and type property.

The target property holds the element that was mutated and type contains the type of mutation that just occurred. We can use these two properties to identify what kind of mutation happened and take the appropriate action.

For instance, we can check if the mutation was an attribute change, a child node change, or a text node change and then act accordingly. type can take the following values:

  • attributes: attribute change
  • characterData: text node change
  • childList: child node change

We can then use this data to take the appropriate action in our callback. For example, if a change to an element’s child nodes is detected, we can update the UI to reflect the new changes.

JavaScript
const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { const type = mutation.type; const element = mutation.target; console.log(`${mutation.type} mutation on element #${element.id}`); } });

Observe changes with Mutation Observer

Once we have created a Mutation Observer, we can use the observe() method to start observing changes in an element. The observe() method takes two arguments: the element to observe and the configuration object. The configuration object can contain options to configure what kind of mutations to watch for. These options include childList, attributes, and characterData.

For example, if we want to watch for changes in an element’s child nodes, we can set the childList option to true. Similarly, if we’re going to watch for changes to attributes and text nodes, we can set the attributes and characterData option to true respectively.

Once we have configured our Mutation Observer and started observing changes, we can react to any changes.

Stop watching for changes in element

Once we have started observing changes, we can stop watching for changes at any time by calling the disconnect() method on the Mutation Observer. This will immediately stop watching for changes in the element, and the observe() method will no longer be called. This can be useful when you no longer need to watch for changes in an element and want to free up memory and resources.

JavaScript
observer.disconnect();

Use MutationObserver in the real-world

In many cases, you may encounter an external script that brings a range of valuable features and capabilities but brings about unwanted visual effects, like displaying text with content you’d like to customize but can’t. In this type of scenario, Mutation Observer can be used as a workaround. This tool can detect when the text content is changed in the DOM and automatically replace it with something more suitable for the task.

Get all pending mutations with takeRecords()

Mutation Observer is a powerful JavaScript API that detects changes to DOM tree elements, such as added/removed components, changed attributes, altered text content, and changed styles. A practical use is to detect and customize content set by external scripts. Create a Mutation Observer with a callback function and use observe() it to start monitoring and disconnect() to end it. takeRecords() retrieves all pending Mutation Records.

How to Get the Current Mouse Position in JavaScript

To get the current position of the mouse in JavaScript, add a mousemove event listener to the window object and access the clientX and clientY properties of the MouseEvent object in the listener to get the X and Y coordinates of the mouse respectively.

For example:

HTML
<p> Mouse pos: <b><span id="mouse-pos"></span></b> </p>
JavaScript
const mousePosText = document.getElementById('mouse-pos'); let mousePos = { x: undefined, y: undefined }; window.addEventListener('mousemove', (event) => { mousePos = { x: event.clientX, y: event.clientY }; mousePosText.textContent = `(${mousePos.x}, ${mousePos.y})`; });
The current mouse position is shown.
The current mouse position is shown.

The mousemove event is triggered on an element when the mouse hovers it. To be more precise, it is fired when the mouse is moved and the cursor’s hotspot is within the element’s bounds.

We attach the event listener to the window object to trigger the event whenever the mouse has moved anywhere on the page.

The mousemove event listener receives a MouseEvent object used to access information and perform actions related to the event. We use the clientX and clientY properties of this object to get the position of the mouse on the X-coordinate and Y-coordinate respectively in the application’s viewport.

Get current mouse position relative to element in React

In the first example, we get the current mouse position in global coordinates. In global coordinates, position (0, 0) is at the top-left of the webpage and position (Xmax, Ymin) is at the bottom right.

We might instead want to get the mouse position within the region of an element.

To get the current mouse position relative to an element, set a mousemove event handler on the element, then calculate the local X and Y positions using properties of the MouseEvent object passed to the event handler.

For example:

HTML
<div> <div class="local"> Local <br /> <b><span id="local-mouse-pos"></span></b> </div> <p> Global <br /> <b><span id="global-mouse-pos"></span></b> </p> </div>
CSS
.local { border: 1px solid #c0c0c0; padding: 75px; text-align: center; display: inline-block; margin-left: 100px; margin-top: 100px; }
JavaScript
const globalMousePosText = document.getElementById('global-mouse-pos'); const localMousePosText = document.getElementById('local-mouse-pos'); let localMousePos = { x: undefined, y: undefined }; let globalMousePos = { x: undefined, y: undefined }; window.addEventListener('mousemove', (event) => { const localX = event.clientX - event.target.offsetLeft; const localY = event.clientY - event.target.offsetTop; localMousePos = { x: localX, y: localY }; globalMousePos = { x: event.clientX, y: event.clientY }; globalMousePosText.textContent = `(${globalMousePos.x}, ${globalMousePos.y})`; localMousePosText.textContent = `(${localMousePos.x}, ${localMousePos.y})`; });

Now the resulting X and Y coordinates will be relative to the element. For example, position (0, 0) will be at the top left of the element, not the viewport:

The current mouse position relative to the element in shown.
The current mouse position relative to the element is shown.

We subtract the offsetLeft property of the element from the clientX property of the MouseEvent object to get the position on the X-axis relative to the element.

Similarly, to get the position on the Y-axis, we subtract the offsetTop property from the clientY property of the MouseEvent object.

JavaScript
window.addEventListener('mousemove', (event) => { const localX = event.clientX - event.target.offsetLeft; const localY = event.clientY - event.target.offsetTop; localMousePos = { x: localX, y: localY }; // ... });

The offsetLeft property returns the number of pixels between the left position of an element and its parent.

Likewise, the offsetTop property returns the number of pixels between the top position of an element and its parent.

How to Check if String Contains Whitespace in JavaScript

To check if a string contains whitespace in JavaScript, call the test() method on this regex: \s, i.e., /\s/.test(str). test() will return true if the string contains any whitespace character. Otherwise, it will return false.

JavaScript
function containsWhitespace(str) { return /\s/.test(str); } console.log(containsWhitespace(' ')); // true console.log(containsWhitespace('JavaScript')); // false console.log(containsWhitespace('coding beauty')); // true console.log(containsWhitespace('string\twith\ttabs')); // true console.log(containsWhitespace('string\nwith\nnewline')); // true

The RegExp test() method searches a string for matches with a regular expression. It returns true if any matches are found. Otherwise, it returns false.

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

The \s matches any single whitespace character in the string.

This method will match any whitespace character, including:

  • space (' ')
  • tab (\t)
  • carriage return (\r)
  • line feed (\n), and
  • vertical tab (\v)
JavaScript
// space (' ') console.log(containsWhitespace('coding beauty')); // true // carriage return (\r) console.log(containsWhitespace('coding\rbeauty\r')); // true // line feed (\n) console.log(containsWhitespace('coding\nbeauty\n')); // true // form feed (\f) console.log(containsWhitespace('coding\f\beauty\f')); // true // vertical tab (\v) console.log(containsWhitespace('coding\vbeauty\v')); // true

If you only to check if the string contains a space character, you’ll need to use a different approach…

Check if string contains only spaces

To check if a string contains only spaces, simply change the regex to a space character:

JavaScript
function containsWhitespace(str) { return / /.test(str); } console.log(containsWhitespace('coding beauty')); // true console.log(containsWhitespace('coding\rbeauty\r')); // false console.log(containsWhitespace('coding\nbeauty\n')); // false console.log(containsWhitespace('coding\f\beauty\f')); // false console.log(containsWhitespace('coding\vbeauty\v')); // false

You can also use call the String includes() methods with a space character to check if such a character exists in the string.

JavaScript
function containsWhitespace(str) { return str.includes(' '); } console.log(containsWhitespace('coding beauty')); // true console.log(containsWhitespace('coding\rbeauty\r')); // false console.log(containsWhitespace('coding\nbeauty\n')); // false console.log(containsWhitespace('coding\f\beauty\f')); // false console.log(containsWhitespace('coding\vbeauty\v')); // false

Check if string contains whitespace with String match()

We can use the call the match() method on a string with the /\s/ as an argument to check whether the string contains whitespace.

JavaScript
function containsWhitespace(str) { return Boolean(str.match(/\s/)); } console.log(containsWhitespace(' ')); // true console.log(containsWhitespace('JavaScript')); // false console.log(containsWhitespace('coding beauty')); // true console.log(containsWhitespace('string\twith\ttabs')); // true console.log(containsWhitespace('string\nwith\nnewline')); // true

Like the RegExp test() method, match() searches a string for matches with a regular expression, but it returns an array of the matches, instead of a boolean value.

JavaScript
// [ ' ', index: 6, input: 'coding beauty', groups: undefined ] console.log('coding beauty'.match(/\s/));

In this case, match() returns an array that contains the first match of a whitespace character, along with some additional properties that provide more information on the match.

If there are no matches found in the string, match() returns null:

JavaScript
console.log('Coding_Beauty'.match(/\s/)); // null

Because of how match() works, we can cast the return value to a boolean, whose value would indicate whether or not any matches of a whitespace character exist in the string.

The Boolean() constructor casts a truthy or false value to true or false. An array of matches from match() will be cast to true, indicating the presence of matches, and a null value from match() will be cast to false, meaning that no matches can be found.

Note: In JavaScript, there are six falsy values: undefined, null, NaN, 0, '' (empty string), and false. Every other value is truthy.

How to Add a Class to All Elements With JavaScript

To add a class to all HTML DOM elements using JavaScript:

  1. Get a list of all the elements in the DOM with document.querySelectorAll('body *').
  2. Iterate over the list with forEach().
  3. For each element, call classList.add(class) to add the class to each element.

i.e.:

JavaScript
const elements = document.querySelectorAll('body *'); // const allElementsOfParentWithClass = document.querySelectorAll('.class *'); // const allElementsOfParentWithId = document.querySelectorAll('#id *'); // const allElementsOfParentWithTag = document.querySelectorAll('tag *'); elements.forEach((element) => { element.classList.add('class'); });

For example:

HTML
<p class="big bold text">Coding</p> <p class="big bold text">Beauty</p> <div class="container"> <p class="big text">Dev</p> <button class="big btn raised">Visit</button> </div> <br /> <button id="add">Add class</button>
CSS
.bold { font-weight: bold; } .big { font-size: 1.5em; } .text { font-family: Arial; } .btn { color: white; background-color: blue; }
JavaScript
const addBtn = document.getElementById('add'); addBtn.addEventListener('click', () => { const elements = document.querySelectorAll('*'); elements.forEach((element) => { element.classList.add('big'); }); });

This will be the HTML after the button is clicked:

HTML
<p class="big bold text">Coding</p> <p class="big bold text">Beauty</p> <div class="big container"> <p class="big bold text">Dev</p> <button class="big btn">Visit</button> </div> <br class="big" /> <button id="add">Add class</button>
The class is added to all elements when the button is clicked.
The class is added to all elements when the button is clicked.

The Dev text and Visit button are larger than other elements in font size, because font-size: 1.2em from the big class is applied to their .container parent, and also to them individually, so they each have a resulting font-size of 1.44em relative to the root element.

We use the document.querySelectorAll() method to select all the DOM elements

We loop through the elements in the list object with its forEach() method. This forEach() method works similarly to Array forEach().

classList.add() method

We use the classList.add() method to add a class to the elements. You can add multiple classes by passing more arguments to add().

JavaScript
const addBtn = document.getElementById('add'); addBtn.addEventListener('click', () => { const elements = document.querySelectorAll('body *'); elements.forEach((element) => { element.classList.add('big', 'blue'); }); });

If any of the classes passed to add() already exists on the element, add() will ignore this, instead of throwing an error.

Add class to all child elements of element

If we want, we could instead add a class to all child elements of a parent that has a specific selector, such as an ID, class, or tag. For instance, we could have done this for the .container element.

To do this, we just need to prefix the * with the element’s selector and separate them with a space. Like we did for body * to get all the elements in the body tag.

JavaScript
const addBtn = document.getElementById('add'); addBtn.addEventListener('click', () => { const elements = document.querySelectorAll('.container *'); elements.forEach((element) => { element.classList.add('big'); }); });
The class is added to all elements in the .container when the button is clicked.
The class is added to all elements in the .container when the button is clicked.

Remove class from all elements

Just like the classList.add() method adds one or more classes to an element, the classList.remove() remove one or more classes from an element. This means that we can use it in the forEach() method to remove a class from all DOM elements.

JavaScript
const elements = document.querySelectorAll('body *'); elements.forEach((element) => { element.classList.remove('big', 'bold'); });

How to Fix the “Cannot read property ‘toString’ of undefined” Error in JavaScript

The “Cannot read property ‘toString’ of undefined” error occurs in JavaScript when you call the toString() on a variable that unexpectedly has a value of undefined.

The "Cannot read property 'toString' of undefined" error occurring

To fix it, try one of the following:

  1. Add an undefined check on the variable.
  2. Ensure the variable is initialized.
  3. Ensure you’re not trying to access the variable from a non-existent index in the array.

1. Add undefined check on variable

a. Use if statement

We can use an if statement to check if the variable is truthy before calling the toString() method.

JavaScript
const obj = undefined; let result = undefined; if (obj) { result = obj.toString(); } console.log(result); // undefined

b. Use optional chaining

We also use the optional chaining operator ?. to return undefined and prevent the method access if the variable is null or undefined.

JavaScript
const obj = undefined; const result = obj?.toString(); console.log(result);

We can use the ?. operator for as many levels as possible.

This:

JavaScript
if (a?.b?.c?.d?.e) { console.log('property "e" is not undefined'); }

is equivalent to the following:

JavaScript
if (a && a.b && a.b.c && a.b.c.d && a.b.c.d.e) { console.log('property "e" is not undefined'); }

c. Call toString() on fallback value

We can use the nullish coalescing operator (??) to provide a fallback value to call toString() on:

JavaScript
const num = undefined; const numStr = (num ?? 10).toString(); console.log(numStr); // 10 const date = undefined; const dateStr = (date ?? new Date()).toString(); console.log(dateStr); // Fri Jan 13 2023 20:07:10

The null coalescing operator (??) returns the value to its left if it is not null or undefined. If it is, then ?? returns the value to its right.

JavaScript
console.log(5 ?? 10); // 5 console.log(undefined ?? 10); // 10

The logical OR operator (||) can also do the same:

JavaScript
console.log(5 || 10); // 5 console.log(undefined || 10); // 10

d. Use a fallback result instead of calling replace()

We can combine the optional chaining operator (?.) and the nullish coalescing operator (??) to provide a fallback value to use as the result, instead of performing the replacement.

JavaScript
const num = undefined; const numStr = num?.toString() ?? 'no number'; console.log(numStr); // 10 const date = undefined; const dateStr = date?.toString() ?? 'no date'; console.log(dateStr); // Fri Jan 13 2023 20:07:10

2. Ensure variable is initialized

The solutions above are handy when we don’t know beforehand if the variable will be undefined or not. But there are situations where the “Cannot read property ‘toString’ of undefined” error is caused by a coding error that led to the variable being undefined.

It could be that you forgot to initialize the variable:

JavaScript
let date; // possibly missing initialized to new Date(); // code... // ❌ Cannot read property 'toString' of undefined console.log(date.toString());

Because an uninitialized variable has a default value of undefined in JavaScript, accessing a property/method causes the error to be thrown.

The obvious fix for the error, in this case, is to assign the variable to a defined value.

JavaScript
let date = new Date(); // possibly missing initialized to new Date(); // ✅ toString() called, no error thrown // Fri Jan 13 2023 20:44:22 console.log(date.toString());

3. Ensure variable is accessed from existing array index

Another common mistake that causes this error is trying to access an element at an index that doesn’t exist in the array.

For example:

JavaScript
const dates = [new Date('2020-05-17'), new Date('2021-08-11')]; const dateStrs = []; // ❌ Cannot read properties of undefined (reading 'toString') for (let i = 0; i <= dates.length; i++) { dateStrs.push(dates[i].toString()); } console.log(dateStrs);

We get the error in the example, because the for loop’s condition makes it perform an iteration where i is equal to dates.length. As the last index if dates.length - 1, accessing index dates.length will result in undefined.

The fix in this particular case is to change the <= to <, to make the loop stop after the iteration where i is the last index.

JavaScript
const dates = [new Date('2020-05-17'), new Date('2021-08-11')]; const dateStrs = []; // ✅ loop executes successfully - no error for (let i = 0; i < dates.length; i++) { dateStrs.push(dates[i].toString()); } console.log(dateStrs); // ['Sun May 17 2020 00:00:00...', 'Wed Aug 11 2021 00:00:00...'];

If you’re not sure that the index exists in the array, you can use the ?. operator like we did previously.

JavaScript
const dates = [new Date('2020-05-17'), new Date('2021-08-11')]; // No error console.log(dates[50]?.toString()); // undefined

How to Detect a URL Change With JavaScript

JavaScript has no native event for listening for URL changes in the browser, so to do this, you can create an interval listener that compares the current URL value to the previous value every X seconds.

JavaScript
let prevUrl = undefined; setInterval(() => { const currUrl = window.location.href; if (currUrl != prevUrl) { // URL changed prevUrl = currUrl; console.log(`URL changed to : ${currUrl}`); } }, 60);

We call setInterval() with a callback and 60 to invoke the callback every 60 seconds. In the callback, we check if the current URL is the same as the last URL; if it is, we perform our desired action.

For example:

HTML
<button id="change-url">Change URL</button> <br /><br /> <span id="url-change-indicator"></span>
CSS
#url-change-indicator { white-space: pre; }
JavaScript
const urlChangeIndicator = document.getElementById('url-change-indicator'); let prevUrl = undefined; setInterval(() => { const currUrl = window.location.href; if (currUrl != prevUrl) { // URL changed prevUrl = currUrl; console.log(`URL changed to: ${currUrl}`); urlChangeIndicator.textContent += `New URL: ${currUrl}\r\n`; } }, 60); const changeUrl = document.getElementById('change-url'); changeUrl.addEventListener('click', () => { history.pushState({}, '', 'new-page.html'); });

A URL change is detected right away when the page is first loaded:

A URL change is detected right away when the page is first loaded.

A URL change will also be detected when history.pushState() is called from the Change URL button’s click event listener.

A URL change is detected when `pushState()` is called on button click.

Detect back button click

Apart from pushState(), this approach will also work when the back button is clicked, whether by the user or with a method like history.back().

A URL change is detected on back button click.
A URL change is detected on back button click.

Detect forward button click

The same thing applies to a forward button click or history.forward():

A URL change is detected on forward button click.
A URL change is detected on forward button click.

Use detect-url-change library

Alternatively, you can use the detect-url-change library to quickly change the browser URL.

JavaScript
import detectChangeUrl from 'detect-url-change'; detectChangeUrl.on('change', (newUrl) => { console.log(`URL changed to ${newUrl}`); });

The default export is an observer on which you can attach listeners to perform an action when the URL changes.

For example:

HTML
<button id="change-url">Change URL</button> <br /><br /> <span id="url-change-indicator"></span>
CSS
#url-change-indicator { white-space: pre; } * { font-family: 'Segoe UI'; }
JavaScript
import detectChangeUrl from 'detect-url-change'; const urlChangeIndicator = document.querySelector('#url-change-indicator'); detectChangeUrl.on('change', (newUrl) => { console.log(`URL changed to ${newUrl}`); urlChangeIndicator.textContent += `New URL: ${newUrl}\r\n`; }); const changeUrl = document.getElementById('change-url'); changeUrl.addEventListener('click', () => { history.pushState({}, '', 'new-page.html'); });
A URL change is detected from a pushState() call in the button's click event listener.
A URL change is detected from a pushState() call in the button’s click event listener.

To use detect-url-change like in this example, you’ll first need to install it into your project. You can do this with the following command:

Shell
npm i detect-url-change # Yarn yarn add detect-url-change

You’ll also need to use a bundling tool like Webpack, Rollup, Parcel, etc.

How to Check If Function Returns a Promise in JavaScript

To check if a function returns a Promise in JavaScript, call the function (impossible without doing so), and use the instanceof operator to check if the return value is a Promise object.

For example:

JavaScript
console.log(returnsPromise(func1)); console.log(returnsPromise(func2)); console.log(returnsPromise(func3)); function returnsPromise(func) { return func() instanceof Promise; } function func1() { return new Promise((resolve) => { resolve('Coding Beauty'); }); } async function func2() { return 100; } function func3() { return 'Coding Beauty'; }

Unfortunately, there’s no way to check if a function returns a Promise without invoking it and getting its result.

After getting the return value, we use instanceof to check if it’s a Promise instance.

Ensure Promise return value from function

If you’re checking the function’s return value to convert a possible non-Promise value to a Promise, you can simply wrap the function call in the Promise.resolve() method.

If the function’s return value is a Promise, Promise.resolve() will return that Promise object.

If the function’s return value is not a Promise, Promise.resolve() will return a Promise that will resolve that return value directly.

JavaScript
Promise.resolve(func1()).then((value) => { console.log(value); // Coding Beauty }); Promise.resolve(func2()).then((value) => { console.log(value); // JavaScript; }); // does return Promise function func1() { return new Promise((resolve) => { resolve('Coding Beauty'); }); } // does NOT return Promise function func2() { return 'JavaScript'; }

Check if function is async

It’s also possible to check if a function is async, by checking if the constructor.name property of the function is 'AsyncFunction':

JavaScript
console.log(isAsync(func1)); // false console.log(isAsync(func2)); // true console.log(isAsync(func3)); // false function isAsync(func) { return func.constructor.name === 'AsyncFunction'; } // NOT async, but returns Promise function func1() { return new Promise((resolve) => { resolve('Coding Beauty'); }); } // async, returns Promise too async function func2() { return 100; } // NOT async, returns NON-Promise function func3() { return 'Coding Beauty'; }

Almost every object in JavaScript has a constructor property that returns a Function reference to the constructor function that created the object instance.

JavaScript
const num = 2; const promise = new Promise((resolve) => resolve(100)); const arr = []; const asyncFunc = async () => 'Coding Beauty'; console.log(num.constructor); // [Function: Number] console.log(promise.constructor); // [Function: Promise] console.log(arr.constructor); // [Function: Array] console.log(asyncFunc.constructor); // [Function: AsyncFunction]

After getting the constructor, we use the Function instance name property to get the name of the function.

JavaScript
console.log(num.constructor.name); // Name console.log(promise.constructor.name); // Promise console.log(arr.constructor.name); // Array console.log(asyncFunc.constructor.name); // AsyncFunction

Note that this approach is not very reliable as the value of constructor.name is not fixed. It could easy be changed in a user-defined class to any value, including 'AsyncFunction':

JavaScript
class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } static name = 'AsyncFunction' } const person = new Person('Brandon', 'Evans'); console.log(isAsync(person)); // true (?!) function isAsync(func) { return func.constructor.name === 'AsyncFunction'; }

How to Check if a Variable is a String in JavaScript

To check if a variable is a string in JavaScript, use the typeof operator, i.e., if (typeof variable === 'string'). If the typeof variable returns 'string', then the variable is a string. Otherwise, it is not a string.

For example:

JavaScript
const variable = 'Coding Beauty'; if (typeof variable === 'string') { // 👇 this runs console.log('Variable is string'); } else { console.log('Variable is not string'); }

The typeof operator returns a string that indicates the type of its operand. For primitives, it returns the exact type, e.g., 'number', 'boolean', 'string', etc, for functions, it returns ‘function‘, and for complex or user-defined types, it returns 'object'.

JavaScript
console.log(typeof true); // 'boolean' console.log(typeof 'Coding Beauty'); // 'string' console.log(typeof 100); // 'number' console.log(typeof new Promise(() => {})); // 'object' console.log(typeof function () {}); // 'function' console.log(typeof Symbol()); // 'symbol' console.log(typeof (() => {})); // 'function' console.log(typeof []); // 'object' console.log(typeof {}); // 'object' console.log(typeof undefined); // 'undefined'

typeof undeclared_variable is 'undefined'?

Note that if you mistakenly use typeof on a variable that hasn’t been declared, typeof will not throw an error:

JavaScript
if (typeof undeclared === 'string') { console.log('Variable is string'); } else { console.log('Variable is NOT string'); }

When used on variables that haven’t been declared, typeof returns the string 'undefined':

JavaScript
console.log(typeof undeclared); // 'undefined'

typeof for string wrapper objects

The one instance where typeof won’t work is when the string was created as a wrapper object i.e., using the String() constructor with the new operator.

For such strings, it will return the 'object' string, instead of 'string'.

JavaScript
const strObj = new String('Coding Beauty'); console.log(typeof strObj); // 'object'

However, it’s not a good practice to use wrapper objects, as they serve no use. Wrapper objects are only used internally; when JavaScript auto-boxes a primitive value into an object to access a property on that object.

typeof null is 'object'?

Note that when typeof is used on the null value, it returns the string 'object'

JavaScript
console.log(typeof null) // 'object'

This is because, as stated in the MDN documentation:

In the first implementation of JavaScript, JavaScript values were represented as a type tag and a value. The type tag for objects was 0null was represented as the NULL pointer (0x00 in most platforms). Consequently, null had 0 as type tag, hence the typeof return value "object". (reference)

A fix was proposed for ECMAScript (via an opt-in), but was rejected. It would have resulted in typeof null === "null".

typeof NaN is 'number'?

Also, typeof NaN results in 'number':

JavaScript
console.log(typeof NaN); // 'number'

Because as stated in this StackOverflow answer and the spec, NaN is considered a numeric type in JavaScript.