Categories
JavaScript Answers

How to Convert a String to a Date Object in JavaScript?

Sometimes, we have a date string that we want to convert to a date object in JavaScript.

In this article, we’ll look at how to convert a date string to a date object in JavaScript.

Extract the Parts of the Date String and Pass Them to the Date Constructor

One way to create a JavaScript date object from a date string is to extract the date parts from the date string and pass them all into the Date constructor.

For instance, we can write:

const [year, month, day] = '2020-04-03'.split('-');
const date = new Date(year, month - 1, day);
console.log(date.toDateString());

We call split on the date string with '-' to split the date string by the dash.

Then we destructure the year , month , and day from the split string array.

Next, we pass all of that into the Date constructor.

We’ve to subtract 1 from month since the month’s value that the Date constructor accepts is from 0 to 11, where 0 is for January and 11 is for December.

Then we get ‘Fri Apr 03 2020’ from the toDateString method.

We can also massage a date into an ISO date string and pass that into the Date constructor.

For instance, we can write:

const st = "26.04.2020";
const pattern = /(d{2}).(d{2}).(d{4})/;
const date = new Date(st.replace(pattern, '$3-$2-$1'));
console.log(date)

We get the parts of the date string with the pattern regex object.

Then we call replace on the st string and move the parts with the $ placeholder.

d extract digits.

The number in the curly braces is the number of digits to extract.

$1 is the first extracted part, which is '26'

$2 is the 2nd extracted part, which is '04'

And $3 is the 3rd extracted part, which is '2020' .

The Date constructor will create a UTC date.

So we get that date in string form is 'Sat Apr 25 2020 17:00:00 GMT-0700 (Pacific Daylight Time)’ .

moment.js

We can pass in a date string into moment.js’ moment function to convert it into an object we can manipulate.

For instance, we can write:

const momentDate = moment("12-25-2020", "MM-DD-YYYY");

to create a moment date object with the date string format specified in the 2nd argument.

We can use the isValid method to check for a valid date:

const isValid = moment("abc").isValid()
console.log(isValid)

isValid should false since 'abc' isn’t a valid date.

And we can convert a moment date object to a native JavaScript Date instance with toDate :

const date = moment("12-25-2020", "MM-DD-YYYY").toDate();
console.log(date)

Conclusion

To convert a date string to a JavaScript date object, we can either extract the parts of the date string ourselves and put it into the Date constructor.

Or we can use a third-party library like moment.js to help us make the job easier.

Categories
JavaScript Answers

How to Capture the Content of an HTML Canvas as an Image File?

Sometimes we may want to capture the content of an HTML canvas as an image file.

In this article, we’ll look at ways that we can do that with JavaScript.

Capturing the Canvas

We can capture the canvas by using the toDataURL method that comes with the canvas element object.

For instance, we can write the following HTML:

<canvas></canvas>

Then we can write the following JavaScript to draw some content and capture it as an image file:

const canvas = document.querySelector("canvas");  
const context = canvas.getContext("2d");  
context.fillStyle = "lightblue";  
context.fillRect(50, 50, 100, 100);  
window.location = canvas.toDataURL("image/png");

We get the canvas element with querySelector .

Then we get the canvas context with getContext .

Then we set the fill style with fillStyle .

And we draw a rectangle with fillRect .

Then we just call toDataURL on the canvas with the MIME type of the file we want to generate to capture the canvas and turn it into a base64 string.

Capturing the Canvas to PDF

To capture the canvas and turn it into a PDF, we can use the jaPDF library.

To use it, we write the following HTML:

<script src="https://unpkg.com/jspdf@latest/dist/jspdf.umd.min.js"></script>  
<canvas></canvas>

Then we can add the JavaScript code to do the capture by writing:

const { jsPDF } = window.jspdf;  
const canvas = document.querySelector("canvas");  
const context = canvas.getContext("2d");  
context.fillStyle = "lightblue";  
context.fillRect(50, 50, 100, 100);  
const imgData = canvas.toDataURL("image/png");  
const doc = new jsPDF('p', 'mm');  
doc.addImage(imgData, 'PNG', 10, 10);  
doc.save('sample.pdf');

First we get the jsPDF object from the jspdf global variable added from the script tag.

Then the next 4 lines are the same as in the previous example.

Then we call canvs.toDataURL and assign the returned base64 string to imgData .

Next, we create a new jsPDF document object with the jsPDF constructor.

The first argument is the orientation of the document. p means portait.

The 2nd argument is the unit, and mm is millimeters.

Then we call addImage with imgData to add the image to our document.

The 2nd argument is the format.

The 3rd and 4th arguments are the x and y coordinates of the image relative to the upper edge of the page.

Then we call doc.save with the file name and extension to save the PDF.

Conclusion

We can capture a canvas’ content to an image with the toDataURL method.

And we can put the image into a PDF with the jsPDF library.

Categories
JavaScript Answers

How to Test for Existence of Nested JavaScript Object Key?

JavaScript objects are often nested in other objects.

Also, they’re dynamic.

Therefore, we may have to check if a nested property exists in an object.

In this article, we’ll look at how to check if a nested property exists in an object.

Write Our Own Function

We can write our own JavaScript function to check if a deeply nested property exists in an object.

For instance, we can write:

const checkNested = (obj, ...props) => {
  for (const prop of props) {
    if (!obj || !Object.prototype.hasOwnProperty.call(obj, prop)) {
      return false;
    }
    obj = obj[prop];
  }
  return true;
}

const obj = {
  level1: {
    level2: {
      level3: 'level3'
    }
  }
};

console.log(checkNested(obj, 'level1', 'level2', 'level3'));
console.log(checkNested(obj, 'level1', 'level2', 'bar'));

We create the checkNested function with the obj parameter and the props rest parameters.

obj is the object we’re checking.

props has an array of properties that forms the path to the nested property we’re looking for.

In the function, we loop through the props array to traverse obj to find the nested property.

To do that, we check if obj is falsy or if hasOwnProperty returns false .

If either of them are true , then we know the property doesn’t exist.

So we return false .

We call hasOwnProperty with Object.prototype.hasOwnProperty.call instead of obj.hasOwnProperty since obj.hasOwnProperty can be overridden.

call takes the this value for hasOwnProperty .

prop is the property name string value.

If we get past the if block, then we assign obj to obj[prop] to look one level deeper.

We can do that since the property is an object.

If the whole loop is iterated through successfully, then we return true since the path leads to the property we’re looking for.

We test this function with the obj object, and we can see the first console returns true .

And the 2nd one returns false as expected.

Recursively Check for a Given Property

We can also do the check with a recursive function.

For instance, we can write:

const checkNested = (obj, prop, ...restProps) => {
  if (obj === undefined) {
    return false;
  }
  if (
    restProps.length === 0 &&
    Object.prototype.hasOwnProperty.call(obj, prop)
  ) {
    return true;
  }
  return checkNested(obj[prop], ...restProps);
};

const obj = {
  level1: {
    level2: {
      level3: "level3"
    }
  }
};

console.log(checkNested(obj, "level1", "level2", "level3"));
console.log(checkNested(obj, "level1", "level2", "foo"));

This checkNested function is similar to the one we have before.

The difference is that we get the first property from the path we’re looking for.

And the rest stays in the array.

We check if restProp.length is 0 and if obj has the prop property.

If they’re both true , then we return true since we traversed the whole path and we found the property.

If they’re anything left in restProps , then we call checkNested to drill down one level lower.

And we should get the same result as before.

Optional Chaining Operator

Another way to check if a nested property path exists is to use tyhe optional chaining operator, which is added with ?. .

This operator is new to ES2020.

For instance, we can write:

const obj = {
  level1: {
    level2: {
      level3: "level3"
    }
  }
};

const value1 = obj?.level1?.level2?.level3;
const value2 = obj?.level1?.level2?.foo;
console.log(value1);
console.log(value2);

We should see that value1 is 'level3' and value2 is undefined since the operator returns the property value if the property exists and undefined otherwise.

This lets us reduce the amount of work needed to traverse deeply nested properties safely.

Conclusion

We can test for the existence of a deeply nested JavaScript object property with our own code or the optional chaining operator.

Categories
JavaScript Answers

How to Transform Moment.js Objects to JavaScript Date Objects or Strings?

Moment.js is a useful library that lets us manipulate dates easily.

However, on many occasions, we’ve to convert moment objects back to native JavaScript date objects to let us do things we want.

In this article, we’ll look at how to transform moment.js objects to JavaScript date objects or strings.

The toDate Method

The toDate method that comes with moment objects lets us convert moment objects to native JavaScript date objects.

For instance, we can write:

console.log(moment().toDate());

to convert the moment object that stores the current date-time back to a native JavaScript date object.

And we should get something like:

Fri Feb 19 2021 17:08:49 GMT-0800 (Pacific Standard Time)

from the console log.

Output to a String

We can use the format method to return a formatted date string from the moment object.

For example, we can write:

console.log(moment().format("YYYY-MM-DD HH:mm:ss"));

YYYY is the formatting code for a 4 digit year.

MM is the formatting code for a 2 digit month.

DD is the formatting code for a 2 digit date.

HH is the formatting code for a 2 digit hour.

mm is the formatting code for 2 digit minutes.

ss is the formatting code for 2 digit seconds.

And so, we should get something like:

2021-02-19 17:10:17

from the console log.

Convert Time to its Equivalent in a Given Timezone

We can convert a moment object with a given time to its equivalent in a given time zone.

First, we include the libraries by writing:

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ==" crossorigin="anonymous"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.33/moment-timezone.min.js" integrity="sha512-jkvef+BAlqJubZdUhcyvaE84uD9XOoLR3e5GGX7YW7y8ywt0rwcGmTQHoxSMRzrJA3+Jh2T8Uy6f8TLU3WQhpQ==" crossorigin="anonymous"></script>

The first script tag is for moment.js.

And the 2nd script tag is for moment-timezone.

The 2nd script tag will add the tz method to moment objects to let us convert a time to its equivalent in a different time zone.

For instance, we can write:

moment.tz.add([
  'America/Los_Angeles|PST PDT|80 70|0101|1Lzm0 1zb0 Op0',
  'America/New_York|EST EDT|50 40|0101|1Lz50 1zb0 Op0'
]);
console.log(moment().tz("America/New_York").format("YYYY-MM-DD HH:mm:ss"));

We call moment.tz.add to add the time zone data.

Then we can use that data to do the conversion with the tz method as it’s done in the console log.

tz returns a moment object with the converted time, so we can call format on it to return a formatted date string.

To convert a moment object to its equivalent in UTC, we can use the utc method:

console.log(moment().utc().format("YYYY-MM-DD HH:mm:ss"));

The utc method is built into the core moment.js library, so we don’t need the moment-timezone library to use it.

Conclusion

We can convert moment objects to date objects or strings with various handy methods provided by the moment.js and moment-timezone libraries.

Categories
JavaScript Answers

How to Sort JavaScript Object Property by Values?

Sometimes, we need to sort JavaScript objects by their values.

In this article, we’ll look at various ways to do that in our JavaScript programs.

Sort JavaScript Object Property by Values with Object.entries and Array Methods

We can use JavaScript methods that are built into the Object constructor to get the keys and values of an object as an array.

And then we can use array methods to rearrange them.

For instance, we can write:

const ages = {
  james: 10,
  jane: 9,
  bob: 30
}

const sorted = Object.entries(ages)
  .sort(([, v1], [, v2]) => v1 - v2)
  .reduce((obj, [k, v]) => ({
    ...obj,
    [k]: v
  }), {})
console.log(sorted)

We use the Object.entries method to get an array of array of key-value pairs in from the ages object.

Then we call sort with a callback to sort the values which we destructured from the array returned from Object.entries .

And then we call reduce with a callback to merge the obj object with the k and v key-value pair.

The 2nd argument should be set to an object so we can do the object spread initially.

Therefore, sorted should be:

{jane: 9, james: 10, bob: 30}

Instead of using reduce , we can also use Object.fromEntries to convert the sorted array back to an object.

For instance, we can write:

const ages = {
  james: 10,
  jane: 9,
  bob: 30
}

const sortedArr = Object.entries(ages)
  .sort(([, v1], [, v2]) => v1 - v2)
const sorted = Object.fromEntries(sortedArr)
console.log(sorted)

Object.fromEntries takes an array of array of key-value pairs. The keys are put into the object as property names.

And the values are their corresponding values.

Therefore, we should get the same result as before but written in a shorter way.

Object.keys

Another way to sort an object’s properties by their property values is to get the keys from the Object.keys method.

Then we can do the sorting the same way.

For instance, we can write:

const ages = {
  james: 10,
  jane: 9,
  bob: 30
}

const sorted = Object.keys(ages)
  .sort((key1, key2) => ages[key1] - ages[key2])
  .reduce((obj, key) => ({
    ...obj,
    [key]: ages[key]
  }), {})
console.log(sorted)

Object.keys only return the property name strings of the ages object, so in the sort callback, we’ve to get the value from the ages object to do the sorting.

Also, we’ve to do the same thing in the reduce callback to get the object value from ages .

And at the end, sorted should be the same as in the previous example.

Conclusion

We can use native JavaScript object and array methods to let us sort properties by their values.