Categories
JavaScript Answers

How to Generating a Number Array within a Range with JavaScript?

To generate a number from a minimum to a maximum number, we can do it in a few ways. If we want each entry to increment by 1, we can use the Array.from method. The Array.from method takes an object which has the length property.

To generate a number within a range, like from 1 to 10, we can make a constant for the maximum number and another one for the minimum number. Then the length would be the maximum minus the minimum plus one.

We need to add one since the maximum minus the minimum is one less than the length we want. The second argument of the Array.from method is a function that lets us map the values to the ones we want.

The first parameter is the value of the original array since we didn’t pass in an array into the first argument, this parameter isn’t useful for us.

The second argument is the index of the array, which will range from 0 to the length which we specified as the length property minus 1. So if we want to generate an array of numbers from 1 to 10, we can write:

const max = 10;
const min = 1;
const arr = Array.from({
  length: max - min + 1
}, (v, i) => min + i);
console.log(arr)

In the code above, we specified the length property of the array that we’ll generate, which is max — min + 1 or 10 – 1+1, which is 10. That’s the length we want. In the second argument, we have a function that maps the index i into min + i, which is will be 1 + 0 , 1 + 1 , 1 + 2 , …, up to 1 + 9 . Then if we run the console.log statement in the last line of the code above, we get:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

It’s easy to generate different kinds of number arrays by adjusting the function in the second parameter since it maps to any number we want. To generate the first n odd numbers, we can write:

const arr = Array.from({
  length: 10
}, (v, i) => 2 * i + 1);
console.log(arr)

In the code above, we have a function that generates odd numbers from a formula. 2 * i + 1 always generates an odd number since 2 times any integer is an event number, so if we add 1 to it, then it will become an odd number. It’s useful for any number sequence that has a pattern that can be put into a formula or be expressed in terms of conditionals or other flow control statements.

Categories
JavaScript Answers

How to Get the Hours Difference Between Two Dates with Moment.js?

Moment.js is a popular JavaScript date and time manipulation library that we can use to calculate various things with date and time.

In this library, we’ll look at how to get the hours difference between 2 dates with moment.js

The moment.duration Method

The moment.duration lets us calculate the duration between 2 dates.

We can combine it with the diff method to calculate the hours difference between 2 dates.

For instance, we can write:

const startTime = moment('2021-01-01')  
const end = moment('2021-02-01')  
const duration = moment.duration(end.diff(startTime));  
const hours = duration.asHours();  
console.log(hours)

We call end.diff(startTime) to calculate the difference between end and startTime .

Then we call moment.duration to get the moment duration.

And finally, we call asHours to get the duration as hours.

Therefore, hours is 744 hours.

Moment.js fromNow and from Methods

We can use the fromNow method to get a human readable string of the difference between a date and now.

For instance, we can write:

const diff = moment('2021-01-01').fromNow()   
console.log(diff)

And we get something like ‘2 months ago’ .

We can use moment.js from method to get a human-readable string between the difference between 2 dates.

For instance, we can write:

const a = moment('2021-01-01');  
const b = moment('2021-02-01');  
const diff = a.from(b);  
console.log(diff)

And we get 'a month ago’ as a value of diff since February 1, 2021 is 1 month ahead of January 1, 2021.

Moment.js diff Method with Unit as the Second Argument

We can pass in a second argument to the diff method to return the difference in the unit specified.

For instance, we can write:

const a = moment('2021-01-01');  
const b = moment('2021-02-01');  
const diff = a.diff(b, 'hours');  
console.log(diff)

We get the difference between date-time a and b .

And a is behind b by 1 month, so we get -744 as the result of diff .

The 2nd argument is 'hours' so the result is in hours.

Conclusion

We can get the difference between 2 dates with the units we specified with various moment.js methods.

Also, we can get human readable durations with moment.js.

Categories
JavaScript Answers

How to Detect that an HTML Element’s Dimension has Changed with JavaScript?

Sometimes, we want to detect whether an HTML element’s size has changed.

In this article, we’ll look at how to detect an HTML element that has changed in size.

ResizeObserver

The ResizeObserver API lets us watch for changes in the size of an HTML element.

For instance, we can write:

const div = document.querySelector('div')
const sleep = ms => new Promise((resolve) => setTimeout(resolve, ms));

(async () => {
  for (let i = 0; i < 10; i++) {
    const p = document.createElement('p')
    p.textContent = 'hello'
    div.appendChild(p)
    await sleep(1000)
  }
})();

new ResizeObserver(e => {
  const [{
    borderBoxSize,
    contentBoxSize,
    contentRect,
    devicePixelContentBoxSize: [devicePixelBoxSize]
  }] = e;
  console.log(borderBoxSize, contentBoxSize, contentRect, devicePixelBoxSize)
}).observe(div);

We have a div that we want to watch for size changes.

And we have an async function that adds a p element to the div to change its size every second.

Then we use the ResizeObserver with a callback to watch for size changes.

We call observe to with the div element object to watch for size changes of the div.

In the ResizeObserver callback, we get an event object in the parameter that has info about the element being watched.

We get a few properties in the e object.

The borderBoxSize property lets us get the border-box size of the observed element.

The contentBoxSize property lets us get the content box size of the observed element.

The contentRect property lets us get the new size of the observed element.

The devicePixelContentBoxSize property has the new content-box size in device pixels of the observed element.

These properties are all objects.

borderBoxSize , contentBoxSize , and contentRect properties has the blockSize and inlineSize properties which has the size in pixels depending on whether the element is a block or inline element.

contentRect has the coordinates of the rectangle with the left , right , top and bottom properties.

left and top have the coordinates of the x and y top-left corner in pixels.

right and bottom have the coordinates of the x and y bottom-right corner in pixels.

x and y also have the coordinates of the x and y top-left corner in pixels.

Conclusion

We can use the ResizeObserver API to watch for size changes of a given HTML element.

Categories
JavaScript Answers

How to Watch for DOM Changes with JavaScript?

Sometimes, we may want to watch for changes in the DOM in our web app.

In this article, we’ll look at how to watch for changes in the DOM with JavaScript.

MutationObserver

One way to watch for DOM changes in our JavaScript web app is to use the MutationObserver constructor.

For instance, we can write:

const observer = new MutationObserver((mutations, observer) => {
  console.log(mutations, observer);
});

observer.observe(document, {
  subtree: true,
  attributes: true
});

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

(async () => {
  for (let i = 0; i < 5; i++) {
    const p = document.createElement('p')
    p.textContent = 'hello'
    document.body.appendChild(p)
    await sleep(1000)
  }
})();

to create the MutationObserver instance with a loop to append child elements to the body within the async function.

We insert a new p element after 1 second 5 times.

We pass in a callback into the MutationObserver constructor that runs when the DOM changes.

Then we call observe on the element that we want to observe changes for.

subtree set to true means that we watch for child element changes.

attributes set to true means we watch for element attribute changes.

Other options include:

  • childList — set to true to observe the target’s children
  • characterData— set to true to observe the target’s data
  • attributeOldValue— set to true to observe the element’s attribute’s value before the DOM change
  • characterDataOldValue— set to true to observe the target’s character data before a change is made
  • attributeFilter — set to the attribute’s local names to be observed.

The mutations parameter has a bunch of properties that have the changes applied.

The mutations.target property has the target element that’s changed.

mutations.target.lastChild has the bottommost child node in the element being watched.

mutations.target.lastElementChild has the bottommost child element node in the element being watched.

Listen to the DOMSubtreeModified Event

Another way to listen for DOM strucuter changes is to listen to the DOMSubtreeModified event.

For instance, we can write:

document.addEventListener('DOMSubtreeModified', (e) => {
  console.log(e)
})

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

(async () => {
  for (let i = 0; i < 5; i++) {
    const p = document.createElement('p')
    p.textContent = 'hello'
    document.body.appendChild(p)
    await sleep(1000)
  }
})();

to add an event listener for the document’s DOMSubtreeModified event.

The e parameter is an MutationEvent object.

The e.target property has the element that’s changed.

e.path has the path to the element that’s changed as an array of elements leading to the changed element.

e.children has an HTMLCollection object with the elements changed.

Conclusion

We can use the MutationObserver and the DOMSubtreeModified event to listen for changes to the DOM.

Categories
JavaScript Answers

How to Extend the JavaScript Error Constructor?

To throw errors in our JavaScript apps, we usually through an object that’s the instance of the Error constructor.

In this article, we’ll look at how to extend the JavaScript Error constructor with our own constructor.

Create Our Own Constructor Function

One way to extend the built-in Error constructor is to create our own constructor that gets data from the Error constructor.

For instance, we can write:

function MyError(message) {
  this.name = 'MyError';
  this.message = message;
  this.stack = (new Error()).stack;
}
MyError.prototype = new Error();
throw new MyError('error occurred')

We create the MyError constructor that takes the message parameter.

We set message as the value of the message property.

And we get the stack trace from the stack property of the Error instance.

We set MyError.prototype to a new Error instance so that a MyError instance is also an Error instance.

In the constructor, we set the name which will be logged when an error is thrown.

Then we throw a MyError instance with the throw keyword.

Once the error, is thrown, we should see it in the log.

And if we log myError instanceof Error and myError instanceof MyError , we should see that both are true since we set MyError.prototype to a new Error instance.

Use the Class Syntax and extends Keyword to extend the Error Constructor

The class syntax is added to ES6 so that we can create constructors that inherit constructors easily.

However, underneath the syntactic sugar, prototypical inheritance is still used as we have in the previous example.

To extend the Error constructor, we write:

class MyError extends Error {
  constructor(message) {
    super(message);
    this.name = 'MyError';
  }
}

const myError = new MyError('error occurred')
console.log(myError instanceof Error)
console.log(myError instanceof MyError)
throw myError

We create the MyError class with the extends keyword to create a subclass of the Error class.

The constructor takes the message parameter and we pass that into the Error constructor by calling super .

We also set our own name property in the constructor.

And then we instantiate the MyError class the same way as before.

And if we use the instanceof operator on Error and MyError , we see that they’re both true .

When we throw an error, we see the message as we did before.

Conclusion

We can use regular prototypical inheritance or the class syntax to create our own constructor that inherits data from the Error constructor.