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.
Let’s learn how to easily subtract any number of minutes from a Date object in JavaScript.
1. DategetMinutes() and setMinutes() methods
To subtract minutes from a Date:
Call the getMinutes() method on the Date to get the minutes.
Subtract the minutes.
Pass the difference to the setMinutes() method.
For example:
function subtractMinutes(date, minutes) {
date.setMinutes(date.getMinutes() - minutes);
return date;
}
// 2:20 pm on May 18, 2022
const date = new Date('2022-05-18T14:20:00.000Z');
const newDate = subtractMinutes(date, 10);
// 2:10 pm on May 18, 2022
console.log(newDate); // 2022-05-18T14:10:00.000Z
Our subtractMinutes() function takes a Date object and the number of minutes to subtract as arguments. It returns the same Date object with the minutes subtracted.
The DategetMinutes() method returns a number between 0 and 59 that represent the minutes of a particular Date.
The DatesetMinutes() method set the minutes of a Date to a specified number.
If the minutes subtracted decrease the hour, day, month, or year of the Date object, setMinutes() will automatically update the information in the Date to reflect this.
// 10:10 am on March 13, 2022
const date = new Date('2022-03-13T10:10:00.000Z');
date.setMinutes(date.getMinutes() - 30);
// 9:40 am on March 13, 2022
console.log(date); // 2022-05-18T14:10:00.000Z
In this example, decreasing the minutes of the Date by 30 rolls the hour back by 1.
Avoiding side effects
The setMinutes() method mutates the Date object it is called on. This introduces a side effect into our subtractMinutes() function. To avoid modifying the passed Date and create a pure function, make a copy of the Date and call setMinutes() on this copy, instead of the original.
function subtractMinutes(date, minutes) {
// π make copy with "Date" constructor
const dateCopy = new Date(date);
dateCopy.setMinutes(date.getMinutes() - minutes);
return dateCopy;
}
const date = new Date('2022-02-20T11:25:00.000Z');
const newDate = subtractMinutes(date, 5);
// 11:20 am on Feb 20, 2022
console.log(newDate); // 2022-02-20T11:20:00.000Z
// π Original not modified
console.log(date); // 2022-02-20T11:25:00.000Z
Tip:Β Functions that donβt modify external state (i.e., pure functions) tend to be more predictable and easier to reason about, as they always give the same output for a particular input. This makes it a good practice to limit the number of side effects in your code.
2. date-fns subMinutes() function
Alternatively, we can use the subMinutes() function from the date-fns NPM package to quickly subtract minutes from a Date in JavaScript. It works like our pure subtractMinutes() function.
import { subMinutes } from 'date-fns';
const date = new Date('2022-10-03T20:50:00.000Z');
const newDate = subMinutes(date, 25);
// 8:25 pm on October 3, 2022
console.log(newDate); // 2019-02-20T11:20:00.000Z
// Original not modified
console.log(date); // 2022-02-20T11:25:00.000Z
To remove all classes from an element in JavaScript, set the className property of the element to an empty string (''), i.e., element.className = ''. Setting the className property to an empty string will eliminate every class in the element.
const box = document.getElementById('box');
// π Remove all classes from element.
box.className = '';
The className property is used to get and set the value of the class attribute of a specified element.
Setting className to an empty string effectively removes all the classes from the element.
Remove all classes from element with removeAttribute() method
To remove all classes from an element with this approach, call the removeAttribute() method on the specified for the class attribute, i.e., element.removeAttribute('class'). This method will remove the class attribute from the element, effectively removing all the element’s classes.
const box = document.getElementById('box');
// π Remove all classes from element
box.removeAttribute('class');
removeAttribute() takes a name and removes the attribute from an element with that name.
In the first method, the class attribute remains on the element after setting the className property. But using the removeAttribute() method completely removes the class attribute from the element.
If the element doesn’t have a class attribute, removeAttribute() will return without causing an error.
Either of these two methods is fine, it’s up to you which one to pick. I think using the className property is better because it more clearly shows what you’re trying to do.
The “cannot read property ‘0’ of undefined” error occurs when you try to access the 0 index of an array-like variable, but the variable turns out to be undefined. To fix it, initialize the variable to a value of the correct data type before accessing the index.
Depending on your scenario, you might be able to resolve the error by doing one of the following:
Provide a defined fallback value for the variable.
Ensure that the variable has been initialized.
If accessing an index of a nested array, check that none of the outer arrays are undefined.
We’ll be touching on these three solutions in this article.
1. Provide defined fallback value
We can fix the “cannot read property ‘0’ of undefined” error in JavaScript by giving the variable a fallback value before accessing it at a specific index. This solution is beneficial when accessing an array property of an object that might return a value of undefined.
The “cannot read property ‘0’ of undefined” error in JavaScript will occur when you access the 0 index of a variable that is uninitialized. Unintialized variables in JavaScript have a default value of undefined.
let arr;
console.log(arr); // undefined
// β Cannot read properties of undefined (reading '0')
console.log(arr[0]);
const str;
// β Cannot read properties of undefined (reading '0')
console.log(str[0]);
Fixing the error in this case is easy; just set the variable to a value, e.g., an empty array ([]) for arrays, an empty string ('') for strings, etc.
let arr = [];
console.log(arr); // []
// β No error
console.log(arr[0]); // undefined
const str = '';
// β No error
console.log(str[0]); // undefined
3. Check outer arrays for undefined
The “cannot read property ‘0’ of undefined” error can also occur when accessing the 0 index in nested arrays.
For nullish values (undefined or null), the optional chaining operator (?.) returns undefined instead of trying to access the property and causing an error.
Since the 1 index of the outer array returned undefined, the optional chaining operator will prevent the property access.
If the value is not nullish, the ?. operator will perform the property access:
const words = [['javascript']];
console.log(words?.[0]?.[0]); // javascript
console.log(words?.[0]?.[0]?.[0]); // j
The Intersection Observer API is used to asynchronously observe changes in the intersection of an element with the browser’s viewport. It makes it easy to perform tasks that involve detecting the visibility of an element, or the relative visibility of two elements in relation to each other, without making the site sluggish and diminishing the user experience. We’re going to learn all about it in this article.
Uses of Intersection Observer
Before we start exploring the Intersection Observer API, let’s look at some common reasons to use it in our web apps:
Infinite scrolling
This is a web design technique where content is loaded continuously as the user scrolls down. It eliminates the need for pagination and can improve user dwell time.
Lazy loading
Lazy loading is a design pattern in which images or other content are loaded only when they are scrolled into the view of the user, to increase performance and save network resources.
Scroll-based animations
This means animating elements as the user scrolls up or down the page. Sometimes the animation plays completely once a certain scroll position is reached. Other times, the time in the animation changes as the scroll position changes.
Ad revenue calculation
We can use Intersection Observer to detect when an ad is visible to the user and record an impression, which affects ad revenue.
Creating an Intersection Observer
Let’s take a look at a simple use of an Intersection Observer in JavaScript.
The callback function receives an array containing objects of the IntersectionObserverEntry interface. This object contains intersection-related information about an element currently being watched by the Observer.
The callback is called whenever the target element intersects with the viewport. It is also called the first time the Observer is asked to watch the element.
We use the for...of loop to iterate through the entries passed to the callback. We’re observing only one element, so the entries array will contain just the IntersectionObserverEntry element that represents the box, and the for...of loop will have only one iteration.
The isIntersecting property of an IntersectionObserverEntry element returns a boolean value that indicates whether the element is intersecting with the viewport.
When isIntersection is true, it means that the element is transitioning from non-intersecting to intersecting. But when it is false, it indicates that the element is transitioning from intersecting to non-intersecting.
So we use the isIntersection property to set the color of the element to blue as it enters the viewport, and back to black as it leaves.
We call the observe() method on the IntersectionObserver object to make the Observer start watching the element for an intersection.
In the demo below, the white area with the scroll bar represents the viewport. The gray part indicates areas on the page that are outside the viewport and not normally visible in the browser.
Watch how the color of the box changes as soon as one single pixel of it enters the viewport:
Intersection Observer options
Apart from the callback function, the IntersectionObserver() constructor also accepts an options object we use to customize the conditions that must be met for the callback to be invoked.
threshold
The threshold property accepts a value between 0 and 1 that specifies the percentage of the element that must be visible within the viewport for the callback to be invoked. It has a value of 0 by default, meaning that the callback will be run once a single pixel of the element enters the viewport.
Let’s modify our previous example to use a threshold of 1 (100%):
We pass 5 percentage values in an array to the threshold property and display each value as the element reaches it. To do this we use the intersectionRatio property, a number between 0 and 1 indicating the current percentage of the element that is in the viewport.
Notice how the text shown doesn’t always match our thresholds, e.g., 2% was shown for the 0% threshold in the demo. This happens because when we scroll fast and reach a threshold, by the time the callback can fire to update the text, we have already scrolled in more of the element beyond the threshold.
If we scrolled more slowly the callback would have time to update the text before the element scrolls past the current threshold.
rootMargin
The rootMargin property applies a margin around the viewport or root element. It accepts values that the CSS margin property can accept e.g., 10px 20px 30px 40px (top, right, bottom, left). A margin grows or shrinks the region of the viewport that the Intersection Observer watches for an intersection with the target element.
Here’s an example of using the rootMargin property:
index.js
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
const intersecting = entry.isIntersecting;
entry.target.style.backgroundColor = intersecting ? 'blue' : 'black';
}
},
// π Root margin 50px from bottom of viewport
{ rootMargin: '50px' }
);
const box = document.getElementById('box');
observer.observe(box);
After setting a rootMargin of 50px, the viewport is effectively increased in height for intersection purposes, and the callback function will be invoked when the element comes within 50px of the viewport.
The red lines in the demo indicate the bounds of the region watched by the Observer for any intersection.
We can also specify negative margins to shrink the area of the viewport used for the intersection.
Now the callback is fired when a single pixel of the element is more than 50px inside the viewport.
root
The root property accepts an element that must be an ancestor of the element being observed. By default, it is null, which means the viewport is used. You won’t need to use this property often, but it is handy when you have a scrollable container on your page that you want to check for intersections with one of its child elements.
For instance, to create the demos in this article, I set the root property to a scrollable container on the page, to make it easy for you to visualize the viewport and the areas outside it and gain a better understanding of how the intersection works.
Second callback parameter
The callback passed to the IntersectionObserver() constructor actually has two parameters. The first parameter is the entries parameter we looked at earlier. The second is simply the Observer that is watching for intersections.
This parameter is useful for accessing the Observer from within the callback, especially in situations where the callback is in a location where the Observer variable can’t be accessed, e.g., in a different file from the one containing the Observer variable.
Preventing memory leaks
We need to stop observing elements when they no longer need to be observed, like when they are removed from the DOM or after one-time scroll-based animations, to prevent memory leaks or performance issues.
We can do this with the unobserve() method.
new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
doAnim(entry.target);
observer.unobserve(entry.target);
}
});
});
The unobserver() takes a single element as its argument and stops observing that element.
There is also the disconnect() method, which makes the Observer stop observing all elements.
Conclusion
Intersection Observer is a powerful JavaScript API for easily detecting when an element has intersected with the viewport or a parent element. It lets us implement lazy loading, scroll-based animations, infinite scrolling, and more, without causing performance issues and having to use complicated logic.
To get the position of the mouse in React, add a mousemove event handler to the window object and access the clientX and clientY properties of the MouseEvent object to get the X and Y coordinates of the mouse respectively.
The mousemove event is triggered on an element when the mouse hovers on it. To be more precise, it is fired when the mouse is moved and the hotspot of the cursor is within the bounds of the element.
We attach the event listener to the window object to trigger the event whenever the mouse is moved anywhere in the page.
We passed an empty dependencies array to the useEffect hook because we want to add a handler for the mousemove event only once – when the component mounts.
In the cleanup function, we use the removeEventListener() method to remove the event listener previously added and prevent a memory leak when the component is unmounted.
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 viewport of the application.
Get mouse position relative to element in React
In the previous example we were able to get the mouse position in global coordinates.
In global coordinates position (0,0) is at the top left of the webpage and position (Xmax, Ymax) is at the bottom right.
We might instead want to get the mouse position within the region of an element.
To get the mouse position relative to an element in React, set an onMouseMove event handler on the element, then calculate the local X and Y position using properties of the MouseEvent object passed to the event handler.
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 page:
We subtract the offsetLeft property of the element from the clientX property of the MouseEvent object to get the X position relative to the element.
Similarly, to get the Y position, we subtract the offsetTop property of the element from the clientY property of the MouseEvent object.
const handleMouseMove = (event) => {
// Calculate position within bounds of element
const localX = event.clientX - event.target.offsetLeft;
const localY = event.clientY - event.target.offsetTop;
setLocalMousePos({ x: localX, y: localY });
};
The offsetLeft property returns the number of pixels between the left position of an element and that of its parent.
Likewise, the offsetTop property returns the number of pixels between the top position of an element and that of its parent.
The active state variable determines the style that will be applied to the element. When it is false (the default), a certain style is applied.
We set a click event handler on the element, so that the handler will get called when it is clicked. The first time this handler is called, the active variable gets toggled to true, which changes the style of the element.
Note
To prevent the style from changing every time the element is clicked, we can set the state variable to true, instead of toggling it:
We used ternary operators to conditionally set the backgroundColor and color style on the element.
The ternary operator works like an if/else statement. It returns the value before the ? if it is truthy. Otherwise, it returns the value to the left of the :.
const treshold = 10;
const num = 11;
const result = num > treshold ? 'Greater' : 'Lesser';
console.log(result) // Greater
So if the active variable is true, the backgroundColor and color are set to white and black respectively. Otherwise, they’re set to blue and white respectively.
Change element style on click with classes
To change the style of an element on click in Vue, we can also create classes containing the alternate styles and conditionally set them to the class prop of the element, depending on the value of the boolean state variable.
We create two classes (active and non-active) with different styles, then we use the ternary operator to add the active class if the active variable is true, and add the non-active class if otherwise.
The advantage of using classes is that we get to cleanly separate the styles from the template markup. Also, we only need to use one ternary operator.
Change element style on click with event.currentTarget.classList
There are other ways to change the style of an element in Vue without using a state variable.
With classes defined, we can use the currentTarget.classList property of the Event object passed to the click event handler to change the style of the element.
We don’t use a state variable this time, so we add the non-active class to the element, to customize its default appearance.
The click event listener receives an Event object used to access information and perform actions related to the click event.
The currentTarget property of this object returns the element that was clicked and had the event listener attached.
We call the classList.remove() method on the element to remove the non-active class, then we call the classList.add() method on it to add the active class.
Notice that the style of the element didn’t change anymore after being clicked once. If you want to toggle the style whenever it is clicked, you can use the toggle() class of the element to alternate the classes on the element.
The “cannot read property ‘addEventListener’ of null” error occurs in JavaScript when you try to call the addEventListener() method on an element that cannot be found in the DOM. This happens for two main reasons:
Accessing the addEventListener() method on an element absent from the DOM.
Inserting the script tag referencing the JavaScript file at a point above the declaration of the DOM element in the HTML.
We’ll learn how to handle the error for these two scenarios in this article.
Cause 1: Accessing addEventListener() on an element not present in the DOM
When a method like getElementById() or querySelector() method is used to search for an element that doesn’t exist in the DOM, it returns null. And attempting to call the addEventListener() method on a null value will cause the error.
Solve: Ensure correct selector
To fix the “cannot read property ‘addEventListener’ of null” error, make sure the selector used the access the element is properly defined. Ensure that there are no mistakes in the ID or class name, and the correct symbols are used.
Solve: Check for null
To fix the “cannot read property ‘addEventListener’ of null” error, check that the element is not null before calling the addEventListener() method on it.
We can do this with an if statement:
const btn = document.getElementById('does-not-exist');
console.log(btn); // null
// β Check if element exists before calling addEventListener()
if (btn) {
// Not called
btn.addEventListener('click', () => {
alert('You clicked the button');
});
}
When a value is placed in between the brackets of an if statement, it is coerced to a Boolean before being evaluated, i.e., truthy values become true, and falsy values become false. null is a falsy value, so it is coerced to false and the code in the if statement block is never run.
Note: In JavaScript, there are six falsy values: undefined, null, NaN, 0, '' (empty string) and false. Every other value is truthy.
const btn = document.getElementById('does-not-exist');
console.log(btn); // null
// β Check if element exists before calling addEventListener()
// Not called
btn?.addEventListener('click', () => {
alert('You clicked the button');
});
The optional chaining operator (?.) is null-safe way of accessing a property or calling a method of an object. If the object is nullish (null or undefined), the operator prevents the member access and returns undefined instead of throwing an error.
Cause 2: Inserting the script tag above the DOM element
Another common cause of this error is placing the <script> tag referencing the JavaScript file at a point above where the target element is declared.
For example, in this HTML markup:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Coding Beauty Tutorial</title>
<!-- β Script is run before button is declared -->
<script src="index.js"></script>
</head>
<body>
<button id="btn">Sign up</button>
</body>
</html>
the script tag is placed in the head tag, above where the button element is declared, so the index.js file will not be able to access the button element.
To fix the error in this case, move the script tag to the bottom of the body, after all the HTML elements have been declared.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Coding Beauty Tutorial</title>
</head>
<body>
<button id="btn">Sign up</button>
<!-- β Script is run after button is declared -->
<script src="index.js"></script>
</body>
</html>
Now the index.js script file will have access to the button element and all the other HTML elements, because they would have already been declared when the script is run.
index.js
const btn = document.getElementById('btn');
console.log(btn); // HTMLButtonElement object
// β Works as expected
btn.addEventListener('click', () => {
alert('You clicked the button');
});
Solve: Access element in DOMContentLoaded event listener
Another way to fix the “cannot read property ‘addEventListener’ of null” error in JavaScript is to add a DOMContentLoaded event listener to the document, and access the element in this listener. With this approach it won’t matter where we place the script in the HTML.
The DOMContentLoaded event is fired when the browser has fully loaded the HTML, and the DOM tree has been built, but external resources like images and stylesheets may not have loaded. So regardless of where we place the script, the code in the listener is only called after all the declared HTML elements have been added to the DOM.
index.js
document.addEventListener('DOMContentLoaded', () => {
const btn = document.getElementById('btn');
console.log(btn); // HTMLButtonElement object
// β Works as expected
btn.addEventListener('click', () => {
alert('You clicked the button');
});
});
Conclusion
We can fix the “cannot read property addEventListener’ of null” error in JavaScript by ensuring that the correct selector is defined, adding a null check to the element before calling addEventListener(), moving the script tag to the bottom of the body, or accessing the element in a DOMContentLoaded event listener added to the document.
To open a link in a new tab in Vue, create an anchor (<a>) element and set its target attribute to _blank, e.g., <a href="https://wp.codingbeautydev.com" target="_blank"></a>. The _blank value specifies that the link should be opened in a new tab.
The target property of the anchor element specifies where to open the linked document. By default target has a value of _self, which makes the linked page open in the same frame or tab where it was clicked. To make the page open in a new tab, we set target to _blank.
We also set the rel prop to noreferrer for security purposes. It prevents the opened page from gaining any information about the page that it was opened from.
Open link in new tab on button click
Sometimes we’ll prefer a button instead of a link to open the new tab when clicked.
To open a link in a new tab on button click, create a button element and set an click event listener that calls the window.open() method.
App.vue
<template>
<div id="app">
<p>
Click this button to visit Coding Beauty in a new tab
</p>
<button
role="link"
@click="openInNewTab('https://wp.codingbeautydev.com')"
>
Click
</button>
</div>
</template>
<script>
export default {
methods: {
openInNewTab(url) {
window.open(url, '_blank', 'noreferrer');
},
},
};
</script>
We use the open() method of the window object to programmatically open a link in a new tab. This method has three optional parameters:
url: The URL of the page to open in a new tab.
target: like the target attribute of the <a> element, this parameter’s value specifies where to open the linked document, i.e., the browsing context. It accepts all the values the target attribute of the <a> element accepts.
windowFeatures: A comma-separated list of feature options for the window. noreferrer is one of these options.
Passing _blank to the target parameter makes the link get opened in a new tab.
When the button is clicked, the event listener is called, which in turn calls window.open(), which opens the specified link in a new tab.
To remove all special characters from a string, call the replace() method on the string, passing a whitelisting regex and an empty string as arguments, i.e., str.replace(/^a-zA-Z0-9 ]/g, ''). The replace() method will return a new string that doesn’t contain any special characters.
For example:
const str = 'milk and @#$%&!bread';
const noSpecialChars = str.replace(/[^a-zA-Z0-9 ]/g, '');
console.log(noSpecialChars); // milk and bread
The Stringreplace() method searches a string for a value (substring or regular expression), and returns a new string with the value replaced by a substring. It doesn’t modify the original string.
The square brackets in the regular expression ([]) indicates a character class. Only characters that are enclosed in it will be matched.
But after placing the caret (^) as the first character in the square bracket, only characters that are not enclosed in the square bracket will be matched.
After the caret, we specify:
ranges for lowercase (a-z) and uppercase (A-Z) letters.
a range for digits from 0-9.
a space character (' ').
So the regex matches any character is not a lowercase or uppercase letter, digit or space, and the replace() method returns a new string with all of these characters removed from the original string.
The g (global) flag specifies that every occurrence of the pattern should be matched.
If we don’t pass a global flag, only the first special character in the string will be matched and removed.
const str = 'milk and @#$%&!bread';
// π No 'g' flag in regex
const noSpecialChars = str.replace(/[^a-zA-Z0-9 ]/, '');
// π Only first special character removed
console.log(noSpecialChars); // milk and #$%&!bread
Shorten regular expression with \w character.
We can shorten this regular expression a bit with the \w character.
const str = 'milk and @#$%&!bread';
const noSpecialChars = str.replace(/[^\w ]/g, '');
console.log(noSpecialChars); // milk and bread
The \w character matches uppercase and lowercase Latin letters, digits, and underscores.
Since \w matches underscores, it can’t be used on its own to remove this special character from a string.
The pipe symbol (|) allows either of two patterns to be matched in a string, similar to a character class. To use the pipe symbol we need to wrap the two patterns in parentheses (( and )), which is what we did.