Categories
JavaScript JavaScript Basics

Introduction to JavaScript Modules

JavaScript modules allow us to divide code into small pieces. They also let us keep some code private while exposing other pieces of code that can be imported into another module.

In this article, we’ll look at how to use define and use them.

Named Exports

Names exports start with the export keyword and they expose items from a module to the outside. Then we can import them somewhere else.

There can be multiple named exports in one module. For instance, we can write:

export const foo = 1;  
export let bar = 1;

Then we can import them into another module as follows:

import { foo, bar } from "./module";
const baz = foo + bar;

We can also import the whole module with the * sign as follows:

import * as module from "./module";
const baz = module.foo + module.bar;

Default Export

We can export one default export using the export default keywords. For instance, we can write:

export default 1;

Then import it as follows:

import foo from "./bar";  
const baz = foo;

We can also export functions and class as follows:

export default () => {};

or:

export default class {}

We don’t need a semicolon at the end of the class export.

Also, we can define default exports with the following code:

const foo = 1;  
export { foo as default };

Browser Differences Between Scripts and Modules

In browsers, scripts are denoted by the script tag. Modules are the same, but it’s denoted by the type attribute with value module .

Scripts are not in strict mode by default, while modules are in strict mode by default.

Top-level variables are global in scrips and are local to the module in modules.

Top-level value of this is window in scripts and it’s undefined in modules.

Scripts are run synchronously while modules are run asynchronously.

There are no import statements in scripts and we can selectively import module members in modules.

We can programmatically import both scripts and modules using promise-based APIs.

Module Characteristics

ES6 modules can be statically analyzed for static checking, optimization, and more. It has a declarative syntax for importing and exporting.

Imports are hoisted to the top so that they can be referenced anywhere in the module.

For instance, if we have:

export const foo = 1;

Then we can import it as follows:

const baz = foo;
import { foo } from "./bar";

Also, they must be at the top-level. Therefore, we can’t have something like:

{  
  import { foo } from "./bar";  
  const baz = foo;  
}

Imports are Read-Only Views on Exports

ES6 imports are read-only views on export entities. Connections to variables inside the module that imported the export remain live.

For instance, if we have:

export const foo = 1;

Then if we have the following:

import { foo } from "./bar";  
foo = 1;

Then we’ll get a ‘”foo” is read-only.’ error since it’s referencing the export directly in a read-only manner.

We get the same result if we change the const to let .

Cyclic Dependencies

If module A and B import members from each other, then we call it a cyclic dependency. This is supported with ES6 modules. For instance, if we have:

index.js :

import { foo } from "./bar";
export const baz = 2;

bar.js :

import { baz } from "./index";
export let foo = 1;

Then the modules are cyclic dependencies since we import a member from bar inindex and we import a member from index in bar .

This works because imports just refer to the original data, so it doesn’t matter when they come from.

Importing Styles

We can import JavaScript modules in various ways. One way is the default import, which is how we import members from a module.

For instance, we can write:

bar.js :

let foo = 1;  
export default foo;

Then we can import it as follows:

import foo from "./bar";

Named imports can be imported as follows. Given the following named exports:

export let foo = 1;

Then we can import it as follows:

import { foo } from "./bar";

We can rename named exports by using the as keyword as follows:

import { foo as baz } from "./bar";

We can also rename default exports as follows:

import { default as foo } from "./bar";

We can also have empty where we don’t import anything. Instead, we run what’s included in the module.

For instance, if we have the following in bar.js :

console.log("bar");

Then we can run the code in bar.js as follows:

import "./bar";

Therefore, we should see 'bar' logged in the console log.

Conclusion

ES6 modules are a great way to divide code into small chunks. We can export module members and import them in another file. Imported members are read-only. Modules are in strict mode by default, so we avoid lots of issues with non-strict mode.

Categories
JavaScript JavaScript Basics

How to Add an ID to Element with Javascript

We can add an ID to a given element with JavaScript.

To do this, first we get the element. We can use the following methods:

  • document.querySelector
  • document.querySelectorAll
  • document.getElementById
  • document.getElementsByTagName

We probably want to use anything other than getElementById since our element doesn’t have an ID yet.

document.querySelector can get an element with any CSS selector and return it.

For instance, given that we have an element with class foo, we can write:

const el = document.querySelector('.foo');

With querySelectorAll, it returns a NodeList with all elements with the given CSS selector.

So we’ve to find the one that’s right for us. But assuming that we want the first element, we can write:

const el = document.querySelectorAll('.foo')[0]

With getElementsByTagName, we can get all the elements by their tag name.

For instance, we can write:

const el = document.getElementsByTagName('div')[0]

to get all the divs with the given name.

In all cases, we can get an HTMLElement object, which has the id property, which we can use to set the ID of an element by assigning a string to it.

We can write:

el.id = 'bar';

to set the ID of el above to bar.

The id property of an HTMLElement can be set to let us add an ID to the element of our choice with JavaScript.

Categories
JavaScript JavaScript Basics

JavaScript Events Handlers — onblur and onerror

In JavaScript, events are actions that happen in an app. They are triggered by various things like inputs being entered, forms being submitted, changes in an element like resizing, or errors that happen when an app is running, etc.

We can assign event handlers to respond to these events. Events that happen to DOM elements can be handled by assigning an event handler to properties of the DOM object for the corresponding events.

In this article, we will look the onblur and the onerror property.

window.document.onblur

The onblur property let’s set an event handler function to it to handle the blur event, where the object that represents the element that can lose focus has lost focus. For example, we can attach a onblur event listener function by writing the following code:

document.onblur = () => {  
  console.log('Document lost focus.');  
};

After adding the code above, when we click outside the page then ‘ Document lost focus.’ should be logged.

window.document.onerror

The onerror property lets us attach an event handler to handle situations when the error event is triggered.

The error event is triggered when a JavaScript run time error occurs, such as when syntax errors or exceptions are being thrown within handlers occurs. The error event handler can take a parameter that has the ErrorEvent object in this case.

These errors get bubbled up to the window object by default. It’s also fired when a resource, like an image or script element, fails to load. An error event using the Event interface will be passed into the error event handler in this case. These errors do not get bubbled up to the window object, but it can be handled in window.addEventListener with useCapture is set to true which is the third argument of the addEventListener method.

For historical reasons, the arguments that are passed into window.onerror are different from the ones that are passed into element.onerror as well as on error-type window.addEventListener handlers. window.onerror’s error handler function has the following function signature:

window.onerror = function(message, source, lineno, colno, error) { ... }

Where message is the error message, the source is the string of the URL of the script that threw the error. The lineno parameter is a number that has the line number where the error was raised. The colno parameter is a number that has the column number for the line where the error occurred. The error parameter has the Error object. The Error object has the following standard properties:

  • constructor — the function that created the instance’s prototype
  • message — the error message
  • name — the error name

It also has vendor-specific properties. For Microsoft browsers, the Error object has the following additional properties:

  • description — the error description, which is similar to message
  • number — the error number

For Mozilla browsers, the following additional properties are added to the error object:

  • fileName — the path to the file that raised the error
  • lineNumber — the line number that raised the error
  • columnNumber — the column number of the line that raise the error
  • stack — the stack trace of the error

If an error event handler is passed into the second argument of the window.addEventListener method, then the function signature of the event handler is significantly different. It should have one event parameter which is the ErrorEvent, so the function signature should be the one below:

window.addEventListener('error', function(event) { ... })

The ErrorEvent inherits all the properties from the Event object plus the following properties are included:

  • message — a read-only property that as the string of the human-readable error message which describes the error
  • filename — a read-only string property that has the name of the script of the file in which the error occurred
  • lineno — a read-only integer that has the line number of the script of the file on which the error occurred
  • colno — a read-only integer that has the column number of the script where the error occurred
  • error — a read-only JavaScript object that has the data about the event

If the onerror is a property of anything other than window, then the event handler that we assign to it should have the same signature as we have above, which is only the event parameter which will have the ErrorEvent passed in when an event occurs.

So with the onerror event handler we can handle any error that occurs when loading the page and running the scripts that are loaded on the page. For example, we can use it to handle the situation when an image fails to load by providing an alternative image which we can load.

For example, if we want to load an image that might exist, then we can add an onerror attribute to the img element to load the fallback image like in the following code:

<img src="invalid.gif" onerror="this.src='[https://images.unsplash.com/photo-1556742521-9713bf272865?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1534&q=80'](https://images.unsplash.com/photo-1556742521-9713bf272865?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1534&q=80');" />

To handle errors during script loading, we can write the following code:

<!DOCTYPE html>  
<html>  
  <head>  
    <title>Error</title>  
  </head>  
  <body>  
    <script src="main.js"></script>  
    <script src="error.js"></script>  
  </body>  
</html>

Then in main.js we add our onerror event handler:

window.onerror = (message, source, lineno, colno, error) => {  
  console.log(message);  
  console.log(source);  
  console.log(lineno);  
  console.log(colno);  
  console.log(error.toString());  
};

Then we put some expressions or statements that throws an error in error.js like the following code:

xyz

Then we should get the error logged in our console.log statements inside the onerror event handler in main.js . We should get something like the following output from the console.log statements:

Uncaught ReferenceError: xyz is not defined  
[http://localhost:3000/error.js](http://localhost:3000/error.js)  
1  
1  
ReferenceError: xyz is not defined

The first console.log output has the error message. The second line in the output has the path to the script that caused the error message. Line 3 has the line number of the script where the error occurred. The fourth line has the column number of the line that caused the error, and the last line has the Error object converted to a string, which returns the error message.

If we instead write use the window.addEventListener method to add the event handler, then we can write the following code to log the ErrorEvent object:

window.addEventListener("error", event => {  
  console.log(event);  
});

Then we should get something like the following output from the console.log statement in the event handler above:

bubbles: false  
cancelBubble: false  
cancelable: true  
colno: 1  
composed: false  
currentTarget: Window {parent: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}  
defaultPrevented: false  
error: ReferenceError: xyz is not defined at [http://localhost:3000/error.js:1:1](http://localhost:3000/error.js:1:1)  
eventPhase: 0  
filename: "[http://localhost:3000/error.js](http://localhost:3000/error.js)"  
isTrusted: true  
lineno: 1  
message: "Uncaught ReferenceError: xyz is not defined"  
path: [Window]  
returnValue: true  
srcElement: Window {parent: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}  
target: Window {parent: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}  
timeStamp: 68.510000128299  
type: "error"

In the output above, we get everything from the Event object plus the additional properties from the ErrorEvent object that we listed above like the error property, message property and the filename property.

Conclusion

With the onblur property, we can set an event handler that can handle the blur event. The onerror property lets us set the event handler for when the error event occurs, which happens when something fails to load like an image or a script that fails to run because of some error.

These are handy event handlers that let us handle user interaction and unexpected errors when resource load respectively.

Categories
JavaScript JavaScript Basics

Formatting Dates with Moment Date Format

With moment.js, we can format dates easily with moment.js.

The list of formatting code that we can use with moment.js are below:

Year, Month, and Day Tokens

  • YYYY – 4 or 2 digit year
  • YY – 2 digit year
  • Y – year with any number of digits and sign
  • Q – quarter of year from 1 to 4
  • M MM – month number
  • MMM MMMM – month name according to the locale
  • D DD – day of the month
  • Do – day of the year
  • X – UNIX timestamp
  • x – UNIX mx timestamp

Week Year, Week, and Weekday Tokens

  • gggg – locale 4 digit week year
  • gg – locale 2 digit week year
  • w ww – locale week of year
  • e – locale day of week
  • ddd dddd – day name
  • GGGG – ISO 4 digit week year
  • GG – ISO 2 digit week year
  • W WW – ISO week of year
  • E – ISO day of week

Locale Aware Formats

  • L – date (in locale format)
  • LL – month name, day of month, year
  • LLL – month name, day of month, year, time
  • LLLL – day of week, month name, day of month, year, time
  • LT – time without seconds
  • LTS – time with seconds

Hour, Minute, Second, Millisecond, and Offset Tokens

  • H HH – hours in 24-hour format from 0 to 23
  • h hh – hours in 12 hours format
  • k kk – hours in 24 hour time from 1 to 24
  • a A – am or pm
  • m mm – minutes
  • s ss – seconds
  • S SS SSS – fractional seconds
  • Z ZZ – offset from UTC

For instance, we can call the format method as follows:

import moment from "moment";
const formattedTime = moment("2010-10-20 4:30").format("YYYY-MM-DD HH:mm");
console.log(formattedTime);

In the code above, we created a moment object with the moment factory function, and then call the format with the format string.

The formatting string is the combination of the parts that are listed above.

It’s very powerful and we can use it to format dates however we like.

Categories
JavaScript JavaScript Basics

How to Add Property to an Object in Javascript

There’re a few ways to add properties to an object in JavaScript.

One way is to add a property using the dot notation as follows:

obj.foo = 1;

We added the foo property to the obj object above with value 1.

We can also add a property by using the bracket notation as follows:

obj['foo'] = 1;

It does the same thing as the first example, but we can have invalid property identifiers in the string.

So we can write something like:

obj['foo-bar'] = 1;

'foo-bar' isn’t a valid identifier, but we can add it as a property.

We can also use the Object.defineProperty function as follows:

Object.defineProperty(obj, 'foo', {
  value: 1
})

We can have more control of how property will act with this method. In addition to setting the value with the value property, we can also set it to be writable or not with the writable property, and set it to be enumerable or not with the enumerable property.

Enumerable means that whether it’ll be retrieved or looped through with Object.keys or the for-in loop.

Writable means whether we can set a new value for the property.

Setting the property to an object with JavaScript is an easy task if we use these 3 ways to do it.