Node.js CheatSheet
NodeGo to video for this category
Node.js is a single-threaded, event-driven JavaScript runtime environment outside the browser, that can run non-blocking, asynchronous I/O operations.
What is Node.js? Define thread (single vs multi), I/O operations
Node.js (is):
- A JavaScript runtime environment that operates outside the browser. Useful for both servers and desktop applications.
- Runs cross-platform, supported by Linux, MacOS, and Windows.
- Consists of:
- A JavaScript runtime environment which includes:
- Google's open sourced V8 JavaScript engine, the same JS engine used by Google Chrome and MS Edge browsers.
- Bindings: Some Node libraries are written in C and C++ so Node provides bindings to convert them from/to JS.
- The libuv library for handling asynchronous I/O operations.
- JavaScript Libraries:
- A core library of JavaScript modules with APIs for interacting with the file system, http, timers, etc.
- A package management system (NPM) for incorporating third party libraries into your project.
- Open source so free to use. Governed by the OpenJS Foundation, which is facilitated by the Linux Foundation's Collaborative Projects program.
- Originally written by Ryan Dahl and released in 2009.
- Operates on a single thread using an event loop. A thread is the smallest sequence of a program that can be managed independently by the operating system's scheduler. Single thread means it executes tasks one at a time blocking other tasks until it completes. Multi-threaded programs can run multiple tasks concurrently. Because JS is single threaded, Browsers have a timeout for tasks that take too long.
- I/O operations are asynchronous (i.e., non-blocking) and event driven allowing other operations to run in parallel while it is completing its task.
- Input/Output operations interact with resources outside Node such as the system disk, database, http requests, etc.
- These are handled by Node's libuv library and passed to the operating system to process in the background.
- I/O tasks that can't be handled asynchronously by the operating system may be passed to a thread pool (making Node multithreaded in these cases).
- When the task is complete it triggers an event and a callback function handles the result.
- Promises, including async/await syntax, can be used in place of a callback function.
- Node does have synchronous (i.e., blocking) I/O functions that can be used if needed.
- Node is frequently used as a web server because its single thread is fast/efficient for a large volume of I/O requests such as HTTP requests. Because it is single threaded it is not a good option for CPU intensive programs.
Definitions
Browser engine, JS engine, V8, runtime, JS runtime environment
- Browser Engine: Web browsers are powered by a browser engine and a JavaScript engine.
- The browser engine transforms HTML documents and other resources (e.g., CSS, images) into a visual/audio representation in the browser.
- They also enforce the security policy between documents, handle form data submissions, hyperlink navigation, and implement the Document Object Model (DOM) data structure accessed by JavaScript.
- Browser engines are not only used in browsers. They are used in email clients to display HTML email.
- Most used browser engines: Google's Blink (used in Chromium-based browsers Chrome and Edge), Mozilla's Gecko (used in Firefox browser), Apple's Webkit (used in Safari browser).
- JavaScript Engine: A computer program that parses the JS code, translates it into machine code, then executes it. They are typically developed by web browser vendors but are now used in non-browser runtime environments as well.
- Most used JS engines: Google's V8 (used in Chromium-based browsers Chrome and Edge, and Node.js), Mozilla's SpiderMonkey (used in Firefox browser), Apple's JavaScriptCore (part of Webkit used in Safari browser).
- V8:
- Google's Definition: "V8 is a JavaScript engine which can run standalone, or be embedded into any C++ application. It compiles JavaScript to machine code before executing it, handles memory allocation for objects, and garbage collects objects it no longer needs."
- Most used JS engine, used in Chromium which powers Google Chrome and Microsoft Edge web browsers, and Node.js.
- V8 is open-sourced under the BSD license.
- Runtime: The period of time when a program is running. Begins when a program is opened (or executed). Ends when the program is closed (or finishes).
- Runtime environment: The hardware and software environment in which a program or application is executed.
- JavaScript runtime environment: The JS engine is one component of the JS runtime environment.
- A web browser is the most common JS runtime environment. It includes a number of Web APIs that the JS code can access. These Web APIs include the Document Object Model allowing JS to manipulate a web page, as well as ajax, fetch, storage, setInterval/setTimeout, console, geolocation, etc.
- The V8 JavaScript engine also runs in the Node.js runtime environment, which allows JS to run on servers and desktops. Instead of Web APIs, Node.js provides APIs for interacting with the file system, HTTP, setInterval/setTimeout, console, etc.
Installation
Install or update Node.js
- Get the version of Node installed on your computer: node --version
- Install/upgrade Node by downloading it from their website nodejs.org/en/download
- Use the Longterm Support (LTS) version unless you specifically need the most current version. For Mac download MacOS Installer (.pkg). Once downloaded click on the .pkg installer file and go with the defaults.
- Npm will automatically be installed/updated when you install Node.
Run Node
Node REPL (Read Eval Print Loop)
- Ref: Nodejs.org/api/repl
- Node's REPL module lets you execute JS and Node commands in the Terminal.
Commands
- node Starts the Node REPL in the Terminal.
- Up/Down Key Returns command history.
- .help
- .load filename.js Load a JS file to the session.
- .save filename.js Save the current Node REPL session to a file.
- Ctrl+C | .break Exits the current expression.
- Ctrl+D | .exit Exits the REPL.
Run Node.js script from a file
- node <filename> default extension is .js
- If there is a path without a filename, node looks for index.js by default.
- node myDirectory is the same as node myDirectory/index.js
- node . is the path to the current directory.
Run Node projects that have a package.json file
- Start Script:
"scripts": { "start": "node server.js" },
- npm start will run node server.js
- Main Property:
"main": "server.js"
- node . runs the "main" file (server.js).
Nodemon
- Start the app: nodemon
- Restart the app: rs
- Stop the app: Ctrl+C
About Nodemon
- The Nodemon package gives you hot reloading. It reloads your app whenever you save a .js, .mjs, .json file that is inside your project directory.
- Ref: npmjs.com/package/nodemon
- Installation: To make it available for all Node apps, install it globally.
npm install nodemon -g
- nodemon command will look for a file to run in this order:
- If there is a filename argument nodemon filename it will run the file.
- If there is no filename arg given, nodemon looks for the default filename
index.js
- Looks for file in package.json:
"main": "filename",
- Looks for a "start" script to run in package.json:
"scripts": {"start": "node filename"},
- If all the above fail, nodemon throws an error.
Node Modules
In Node.js, each file is treated as a separate module.
There are three main sources of modules:
There are three main sources of modules:
- Built-in Node modules. These are installed when you install Node.js.
- 3rd Party packages available on the npmjs.com registry, and elsewhere, for installation.
- User created files and modules.
Import/Export modules
Except for global built-in modules, modules must be exported from their source files and imported before being used. Use either CommonJS or ES6 Import/Export statements.CommonJS Syntax:
Single construct:export:
module.exports = main_construct;
import:
const moduleName = require('filename');
Multiple constructs:
export:
module.exports = { construct1[, construct2,...] };
import:
const { construct1[, construct2, ...] } = require('filename');
Examples
Single construct:
Multiple constructs:
calculator.js (export file)
const calculator = { double: (x) => x * 2, triple: (x) => x * 3 };
module.exports = calculator;
app.js (import file)
const calculator = require('./calculator'); console.log(calculator.double(10)); // logs 20 console.log(calculator.triple(10)); // logs 30
calculator.js (export file)
const double = (x) => x * 2;
const triple = (x) => x * 3;
module.exports = { double, triple };
app.js (import file)
const { double, triple } = require('./calculator'); console.log(double(10)); // logs 20 console.log(triple(10)); // logs 30
ES6 import/export statements:
Single construct:export:
export default main_construct;
import:
import moduleName = from 'filename';
Multiple constructs:
export:
export { construct1[, construct2, ...] };
import:
import { construct1[, construct2, ...] } from 'filename';
Examples
Single construct:
Multiple constructs:
calculator.mjs (export file)
const calculator = { double: (x) => x * 2, triple: (x) => x * 3 };
export default calculator;
app.mjs (import file)
import calculator from './calculator.mjs'; console.log(calculator.double(10)); // logs 20 console.log(calculator.triple(10)); // logs 30
calculator.mjs (export file)
const double = (x) => x * 2;
const triple = (x) => x * 3;
export { double, triple };
app.mjs (import file)
import { double, triple } from './calculator.mjs'; console.log(double(10)); // logs 20 console.log(triple(10)); // logs 30
Global Object
- Window: In the browser, window is the object available in the global scope.
- Global: In node, global is the global object.
- Ref: nodejs.org/api/globals
- Some node modules are attached to the global object. Commonly used Node modules include:
- Timers (e.g., setTimeout()), Console, Process, URL, TextEncoder/TextDecoder.
- Global scoped modules are loaded with the global object so no need to load them with require(moduleName).
- Example: console.log() can be called anywhere in your code.
- The "global" object is implied so global.console.log() works but is unnecessary.
- You can set variables to the global object: global.varName = value;
Set current directory to a global variable: global.__basedir = __dirname;Then use it in any file loaded after declaring it: __basedir + '/path'
NPMGo to video for this category
Npm is automatically installed when you install or upgrade Node.js.
NPM's Package Repository: Npmjs.com
Npm help
npm help prints a list of available commands.npm help command prints info about the command. Uses the Unix less paging program:
- Navigate: downArrow | return down 1 line, upArrow up 1 line, g to start, G to end,
d down 1/2 screen, u up 1/2 screen, f | space forward 1 screen, b back 1 screen.
- Search: /search-term, n next instance, N previous instance.
- Quit: q
Package.json
Ref: docs.npmjs.com/files/package.json
npm init Creates a package.json file to manage 3rd party Node packages, add meta info about your app, and add scripts.
npm init Creates a package.json file to manage 3rd party Node packages, add meta info about your app, and add scripts.
- -y flag to use all defaults.
- Local packages and their dependencies are automatically tracked in package-lock.json.
Scripts
Package.json scripts execute CLI commands. The property name calls the script value.
"scripts": { "scriptName": "some command(s)" },npm run scriptName Run scriptName defined in package.json scripts.
Example
- You are going to build a backend web server with Node.js.
- Your project folder is called mysite. From that folder run: npm init
- Answer the series of project setup questions.
- The "main" property is the file that launches your site. It can be index.js, server.js, app.js or whatever you want.
- The script property is where you can optionally add scripts to run from the command line with npm run scriptName. The property name is the command name. It executes the property value. We'll add three scripts:
"watch"
will run the command nodemon server.js. This will launch our app locally using the nodemon package, assuming it's installed. This is useful in development since every time we save a file, nodemon will automatically restart the app."start"
will start our app for production by running the command node server.js."test"
will run our testing program by calling command jest --coverage. In this example we are using the jest testing library.- Install packages: To run this app we need to install some npm packages:
- Global packages: npm i nodemon location=global Install nodemon as a global package since it is a CLI utility and can be used for any Node project.
- Local packages: npm i express ejs We'll install the express web frame work and the ejs templating packages.
- Development dependencies: npm i jest -D Install the jest testing framework as a development dependency. This package won't be installed on the production server since it is only used in the development environment.
package.json
{ "name": "MySite" "version": "1.0.0", "main": "server.js", "scripts": { "watch": "nodemon server.js", "start": "node server.js", "test": "jest --coverage" }, "dependencies": { "ejs": "^3.1.8", "express": "^4.18.1" }, "devDependencies": { "jest": "^28.1.2" } }
Run Scripts:
Once your files are added and have code you can run the below commands:
npm run watch Runs the watch script to run the server file with nodemon.
npm start Runs the start script in the package.json. Keyword run optional.
npm test Starts the test runner. Keyword run optional.
Install packages. Deletes old version on update.
Alias: i for install
npm install packageName Install or update package locally.
npm install packageName -D | --save-dev As a development dependency.
npm install packageName --global Install or update package globally.
npm install packageName@1.2.3 | @latest Install a specific or latest version.
npm install packageName Install or update package locally.
npm install packageName -D | --save-dev As a development dependency.
npm install packageName --global Install or update package globally.
npm install packageName@1.2.3 | @latest Install a specific or latest version.
Uninstall Packages
npm uninstall packageName --global Uninstall global package.
npm uninstall packageName Uninstall local package.
npm uninstall packageName Uninstall local package.
More details and examples
- Packages are installed from the npm registry by default.
- Packages are listed at npmjs.com
- Local packages are installed in the node_packages folder and added to your package.json file as dependencies or devDependencies.
- Global packages are installed by default on Mac in /usr/local/lib/node_modules with their binary executable files located in the /usr/local/bin directory. When using a version manager like npm they are installed in your user directory.
Examples:
npm i express Install or update express locally.
npm i express@4.18.1 Install or update to a specific version of express locally.
npm i express@latest Install or update to the latest version of express locally.
npm i nodemon --global Install or update nodemon globally.
npm i nodemon -D Install or update nodemon as a development dependency.
Local Packages
Installed in the project's
node_modules
directory. - Production: Package name and version automatically added to
package.json dependencies
. - Development: Development dependencies aren't used in production mode.
Package name and version automatically added topackage.json devDependencies
.
npm install package -D Append-D
or--save-dev
option.
Example
Install packages:
- Local packages: npm i express ejs The express web frame work and the ejs templating packages are integrated into your app and used in production.
- Development dependencies: npm i jest -D The jest testing framework is installed as a development dependency since it is only used on development and not in the production environment. The production environment is the web server that hosts the web site.
package.json
{ ... "dependencies": { "ejs": "^3.1.8", "express": "^4.18.1" }, "devDependencies": { "jest": "^28.1.2" } }
Using local packages in your project
- Import package to a file:
const package = require('packageName');
- Use it in the same file:
package.method();
Example
Express package example:
- Express is a light-weight web application framework.
- At the top of a file that uses the package, import the package as a module with the require function set to the "express" variable name:
const express = require('express');
- The you can use the express variable to access the module methods, variables or other constructs. Express has a method for parsing JSON data:
express.json()
Import express methods using destructuring:
- You can use destructuring to only assign the methods, objects, or variables you need:
const { json, urlencoded, static } = require('express');
- Then use the methods directly:
json()
Global Packages
Packages run from the CLI are generally installed globally or run with npx.--global
or -g
option.sudo npm i package --global | -g If you get a permission error, use sudo.
Run global packages:
packageName [args] Run global packages from the terminal with the pkg name.
Installation location and example
- Nodemon is a package used to run a node project. It uses hot reloading which means it will automatically restart the server when you save a JavaScript or JSON file.
- It is a good candidate for global installation because:
- It is run from the command line.
- It is used frequently across many projects.
- Install nodemon: npm install nodemon --global
- Run your project just by executing the program: nodemon
Installation location:
- On Mac by default are installed in folder:
/usr/local/lib/node_modules/
- Aliases pointing to the package are installed in:
/usr/local/bin/
- If installed with nvm (Node Version Manager), packages are installed in the user's home directory.
npx command
Run a package command in the CLI without installing the package.
npx command [args] Guesses package name from command,
npx command [args] Guesses package name from command,
- Checks if installed locally, then globally. If so, runs it.
- If not, temporarily loads and runs package from a local cache w/o installing it.
Express-generator example
- Express-generator is a package created by the Express team that generates a web application skeleton.
- It is a good candidate for running it with npx because:
- You run it from the command line.
- You probably won't run it too frequently.
- Npx is also useful to try out a new package before deciding whether to install it or not.
- Express-generator takes the project name as the argument:
- npx express-generator appName
- If instead it was installed globally you can run it with:
- express-generator appName
List Installed Package(s)
npm list List locally installed packages and versions.
npm list --depth 1 Include their dependencies 1 level down.
npm list packageName List specific local package with version.
Global packages append option: --global | -g
which packageName Returns the global path to the package's executable file if installed.
packageName --version Returns the version number if installed globally.
npm list --depth 1 Include their dependencies 1 level down.
npm list packageName List specific local package with version.
Global packages append option: --global | -g
which packageName Returns the global path to the package's executable file if installed.
packageName --version Returns the version number if installed globally.
Examples
Run from the myproj directory:
npm list Lists local packages in myproj/node_modules folder.
npm list --depth 1 Lists local packages in myproj/node_modules folder and 1 level of their dependencies.
npm list express Lists the express package with version if it is installed locally.
Get global package info. Can be run from any directory:
npm list --global List globally installed packages.
npm list --depth 1 --global List globally installed packages and 1 level of their dependencies.
npm list nodemon --global Lists the nodemon package with version if it is installed globally.
which nodemon Returns the path to the nodemon package executable file (or its alias) if installed globally.
nodemon --version Returns the version of the nodemon package if installed globally.
npm list Lists local packages in myproj/node_modules folder.
npm list --depth 1 Lists local packages in myproj/node_modules folder and 1 level of their dependencies.
npm list express Lists the express package with version if it is installed locally.
Get global package info. Can be run from any directory:
npm list --global List globally installed packages.
npm list --depth 1 --global List globally installed packages and 1 level of their dependencies.
npm list nodemon --global Lists the nodemon package with version if it is installed globally.
which nodemon Returns the path to the nodemon package executable file (or its alias) if installed globally.
nodemon --version Returns the version of the nodemon package if installed globally.
Get info on a Package
Go to npmjs.com and enter the package name in the search box.
npm search packageName Returns info on Node packages that include packageName
npm view packageName Returns general information about the package.
npm search packageName Returns info on Node packages that include packageName
npm view packageName Returns general information about the package.
Update Packages
NPM uses semantic versioning:
package.json file:
npm view packageName version Return the latest available version of a package.
npm outdated Show all local packages out of date w/ the latest available version.
npm update packageName Update local package and delete old version.
npm update Update all local packages.
npm install packageName@6 Update to major version 6.
Global packages append option: --global | -g
major.minor.patch
. package.json file:
"dependencies": {Symbols:
"pkg1": "1.2.3", // won't update
"pkg2": "~1.2.3", // updates to latest patch version
"pkg3": "^1.2.3" // updates to latest minor and patch version
}
~
update to latest patch version. ^
update to latest minor and patch version. npm view packageName version Return the latest available version of a package.
npm outdated Show all local packages out of date w/ the latest available version.
npm update packageName Update local package and delete old version.
npm update Update all local packages.
npm install packageName@6 Update to major version 6.
Global packages append option: --global | -g
Example
When you install a package, by default it is installed with the ^ symbol. So running npm update on the project will update packages to that latest minor and patch versions, but not the latest major version.
package.json
... "dependencies": {
"ejs": "^3.1.8",
"express": "^4.18.1",
"sequelize": "^6.21.2"
} ...
- To see what packages are not up-to-date run: npm outdated
- It will show you the outdated packages and versions side by side. It will show you what version it will update to if you re-install or update it.
- If the latest ejs version is 4.1.3 which is a major version higher. To update to that version run: npm i ejs@4
Console | Timer | ProcessGo to video for this category
Console Module
- Ref: Nodejs.org/api/console Works similar to the browser equivalent.
- Scoped globally so works w/o require().
- console.log(1, 'Some text'); Log multiple items separated by commas.
- console.log('2: ' + 'Some text'); Concatenate items with +.
- console.log(`1 and 1 is ${1 + 1}`); Template literal with interpolation.
- console.log('3: %s is inserted here', 'Some text'); %s string substitution
Timer Modules
- Ref: Nodejs.org/api/timers Works similar to the browser equivalent.
- Scoped globally so works without require().
SetTimeout
setTimeout(() => {
console.log('logs after 2 seconds');
}, 2000);
SetInterval
setInterval(() => {
console.log('logs every 2 seconds');
}, 2000);
SetInterval with clearInterval
let x = 0; const myInterval = setInterval(() => { if (x < 5) {
console.log(x); } else { clearInterval(myInterval); }
}, 2000);
Explanation
- We assign the setInterval function to a variable so it can be referenced by clearTimeout.
- The setInterval timer is set for every 2000 milliseconds, which is 2 seconds.
- The callback function contains a conditional statement. If x is less than 5 it logs x.
- If x is not less than 5 it calls the clearInterval function which clears the setInterval passed in as the argument. The argument is the myInterval variable.
Process Module
- Ref: Nodejs.org/api/process
- A process is an instance of a program running in a computer.
- The process object provides info about, and control over, the current Node process.
- It is a global so it is available w/o using require().
Get process info using properties and methods:
process.title
Current process title. Returns 'node'.process.version
Version of Node that is running.process.platform
Operating system platform: "darwin" (MacOS), "win32", "linux".process.cwd()
Returns the current working directory of the process (the project).process.env
Returns an object containing the user environmental variables.process.env.PATH
Your system's PATH string. Each path is separated by a colon.Exit the current process:
process.exit()
Forces the current Node process to exit.Standard Input/Output
Standard output writes to the terminal.
Console.log() and console.error() use process.stdout and process.stderr internally.
Console.log() and console.error() use process.stdout and process.stderr internally.
- Write standard output to the console. Unlike console.log() you need to add a new line.
process.stdout.write('Some message.' + '\n')
This is the equivalent ofconsole.log('Some message.')
- Write standard error to the console.
process.stderr.write('Some error message\n')
- Standard input takes user input from the terminal.
- To process the input, listen for the data event with the Events module's on method.
process.stdin.on('data', (input) => { // do something with the input. });
Example: question and answer in the terminal using stdin and stdout
Create a file that runs on the terminal:
- Ask a question. Add > as a response prompt.
- This opens a session of Node.js in the terminal.
- The stdin method processes user standard input from the Terminal.
- Chain the Event module's "on" method, listening for the "data" event.
- The "data" event occurs when the user presses the return key.
- Output a response using that data.
- The default stdin encoding is as a buffer object, so you need to convert it to a string.
- Unless you set the encoding to UTF-8 (a standard encoding for text).
process.stdin.setEncoding('utf8');
- Stdin terminates in a new line. In this case we don't want that new line so chain .trim().
- Exit the process which takes us out of the Node.js terminal session.
// question-answer.js
process.stdout.write('What is your name?\n > ')
process.stdin.on('data', (data) => {
process.stdout.write(`Hi ${data.toString().trim()}!\n`);
process.exit();
});
node question-answer Run the program.
URL | PathGo to video for this category
URL Module
- Ref: nodejs.org/api/url
- Provides utilities for URL resolution and parsing.
- Available on the global object so you don't need to import it before using.
URL Structure
URL structure definitions:
- URL (Uniform Resource Locator): The address of a given unique resource on the Web.
- Protocol (aka the scheme): A set method for exchanging or transferring data around a computer network. For the web it can be http (Hypertext Transfer Protocol) or https (s is for secure). Other protocols: ftp, mailto, file, data, irc.
- Domain Name: Indicates which Web server is being requested.
- IP Address: is the numeric address of the web server. Domain names are translated into their IP address by DNS servers. The request is then routed to the server.
- Domain name example: www.example.com
- Top Level domain: com, org, gov, co, co.uk, etc.
Represents the type of organization you have. E.g., .com for commercial business, .gov for a government website.
- Second level domain: The main name of your site. "Example" in this case.
- Subdomain: A subset of the main domain. For instance Google has subdomains for mail, maps, drive, etc.
www is the generic subdomain for sites on the World Wide Web.
- Port Number: Omitted from web addresses because they are implied. Http requests automatically use port 80, https requests automatically use port 443. Used in computer networks and with localhost when using a local development server.
- Path: Route path to the resource on the Web server.
- Query String: Optional extra parameters in the form of key-value pairs. Used by the server for some specified purpose such as search engines using them to pass in a search term.
If present it starts with a?
. Multiple key-value pairs are separated by&
.
- Fragment: Optional. Indicates a location on a web page. Starts with
#
followed by an id that must match an element id on the page.
URL Object
const url = new URL(url_string);
The below can be used to get or set the property (except where noted)
url.href
The full URL string.url.origin
Protocol, full domain name, and port (URL to the server root). Read only.url.protocol
http | https | ftpurl.host
full domain name and port if any. (e.g., www.example.com | localhost:3000).url.hostname
full domain name. (e.g., www.example.com | localhost).url.port
Port number if present (e.g., 3000).url.pathname
Path to resource on the Web server (e.g., /article/learn-node)url.search
Query string portion of the URL (e.g., ?title=Node&author=Joey+R.).url.searchParams
Query string as an object (e.g., {title: 'Node', author: 'Joey R.'}).url.hash
Fragment portion of the URL (e.g., #intro).
Examples
const url = new URL('https://www.example.com:3000/article
?year=2023&month=december#intro');
/* {
href: 'https://www.example.com:3000/article
?year=2023&month=december#intro',
origin: 'https://www.example.com:3000',
protocol: 'https:',
host: 'www.example.com:3000',
hostname: 'www.example.com',
port: '3000',
pathname: '/article',
search: '?year=2023&month=december',
searchParams: URLSearchParams {
'year' => '2023', 'month' => 'december' },
hash: '#intro'
} */
url.href // https://www.example.com/article?year=2021&month=december
url.origin // https://www.example.com
url.protocol // https:
url.host // www.example.com:3000. Includes port
url.hostname // www.example.com. Excludes port
url.port // 3000
url.pathname // /article
url.search // ?year=2023&month=december
url.searchParams // { year: 2023, month: 'december' }
url.hash // #intro
?year=2023&month=december#intro');
/* {
href: 'https://www.example.com:3000/article
?year=2023&month=december#intro',
origin: 'https://www.example.com:3000',
protocol: 'https:',
host: 'www.example.com:3000',
hostname: 'www.example.com',
port: '3000',
pathname: '/article',
search: '?year=2023&month=december',
searchParams: URLSearchParams {
'year' => '2023', 'month' => 'december' },
hash: '#intro'
} */
url.href // https://www.example.com/article?year=2021&month=december
url.origin // https://www.example.com
url.protocol // https:
url.host // www.example.com:3000. Includes port
url.hostname // www.example.com. Excludes port
url.port // 3000
url.pathname // /article
url.search // ?year=2023&month=december
url.searchParams // { year: 2023, month: 'december' }
url.hash // #intro
Path Module
- Ref: nodejs.org/api/path
- Provides utilities for working with file and directory paths.
- Import the module: const path = require('path');
- CommonJS Modules convenience variables:
- __dirname Gets absolute path to the current file's directory.
- __filename Gets absolute path to the current file.
Get path info
path.parse(path)
Returns object with path elements as properties:- { root: '/', dir: '/Users/steve/nodeApp', base: 'app.js', ext: '.js', name: 'app' }
dir
is the path to the file's directory.base
file name with extension.name
file name w/o ext.ext
file extension.path.dirname(path)
Path to the file directory.path.basename(path)
Last portion of a path, similar to Unix basename command.path.basename(path, ext)
Last portion of a path without the provided extension.path.extname(path)
returns the extension of the path.
Examples
const pathString = '/Users/steve/nodeApp/app.js';
// alternatively get the current file's path: __filename
// Parsed path
const pathObj = path.parse(pathString); // Returns: { root: '/',
dir: '/Users/steve/nodeApp', base: 'app.js', ext: '.js', name: 'app' }
pathObj.dir // /Users/steve/nodeApp
pathObj.base // app.js
pathObj.name // app
pathObj.ext // .js
// Get path elements
path.dirname(pathString) // /Users/steve/nodeApp
path.basename(pathString) // app.js
path.basename(pathString, '.js') // app
path.extname(pathString) // .js
// alternatively get the current file's path: __filename
// Parsed path
const pathObj = path.parse(pathString); // Returns: { root: '/',
dir: '/Users/steve/nodeApp', base: 'app.js', ext: '.js', name: 'app' }
pathObj.dir // /Users/steve/nodeApp
pathObj.base // app.js
pathObj.name // app
pathObj.ext // .js
// Get path elements
path.dirname(pathString) // /Users/steve/nodeApp
path.basename(pathString) // app.js
path.basename(pathString, '.js') // app
path.extname(pathString) // .js
Create path string:
path.join([...paths])
Joins path segments into one path string.path.resolve([...paths])
Resolves paths or path segments into an absolute path.
Examples
Set a path string variable manually:
Use the join method:
Use the resolve method for relative paths:
const pathString = '/Users/steve/nodeApp/app.js';
const pathString = path.join('/Users', 'steve', 'nodeApp', 'app.js');
const pathString = path.join('/Users/steve/nodeApp', 'app.js');
const pathString = path.join(__dirname, 'app.js');
const pathString = path.join('/Users/steve/nodeApp', 'app.js');
const pathString = path.join(__dirname, 'app.js');
const dataPath = path.resolve(__dirname, '../data/myData.json');
File SystemGo to video for this category
File System (fs) Module
- Ref: Nodejs.org/api/fs
- Provides an API for interacting with the file system.
- Import the module:
const fs = require('fs');
- Path arguments can be relative:
'./filename'
- or absolute:
/Users/steve/Documents/filename'
- Most fs methods have both a synchronous and asynchronous version.
Synchronous vs Asynchronous versions
The fs methods interact with the operating system to create, modify or delete files and directories. Node and JavaScript are single threaded so you have two options:
- Synchronous version: Wait for the action to complete before moving on to the next statement. The synchronous versions have "Sync" appended to the method name.
- Asynchronous version: Include a callback function as an argument to the method and go on to the next statement. When the action is completed, the callback function is executed.
Check if path exists
- Check if a directory or file exists.
- Sync:
fs.existsSync('path')
Examples
- Check if file myfile.txt exists:
fs.existsSync('myfile.txt');
- Check if directory mydir exists:
fs.existsSync('mydir');
- Check if myfile.txt exists in the parent directory:
fs.existsSync('../myfile.txt');
- Check if mydir exists as a sibling directory:
fs.existsSync('../mydir');
- In a conditional:
if (fs.existsSync('myfile.txt')) console.log('File exists');
- In a not conditional:
if (!fs.existsSync('myfile.txt')) console.log('File does not exist');
Files
Write to File
- Create a file if it doesn't exist. Replace it if it does.
- Async:
fs.writeFile(file, data[, options], callback)
- Callback function takes err parameter to handle potential errors.
- Sync:
fs.writeFileSync(file, data[, options])
Examples
Asynchronous version:
let content = 'Hello from my text file.';
fs.writeFile('myTextFile.txt', content, (err) => {
if (err) throw err;
});
Synchronous version:
content = 'Hello again from my text file.'
fs.writeFileSync('myTextFile.txt', content);
Append to File
- Append data to the end of the file.
- If the file does not exist it will be created.
- Async:
fs.appendFile(path, data[, options], callback)
- Callback function takes err parameter to handle potential errors.
- Sync:
fs.appendFileSync(path, data[, options])
Examples
Asynchronous version:
Synchronous version:
fs.appendFile('myTextFile.txt', '\nAppend more data.', (err) => {
if (err) throw err;
});
Synchronous version:
fs.appendFileSync('myTextFile.txt', '\nEven more data.');
Read File
- Async:
fs.readFile(path[, options], callback)
- Callback function: first param is err. Second is the file data.
- Sync:
fs.readFileSync(path[, options])
- First option is encoding which for text would generally be 'utf8'.
If no encoding is specified, then the raw buffer is returned.
Examples
Asynchronous version:
Synchronous version:
fs.readFile('myTextFile.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
Synchronous version:
const data = fs.readFileSync('myTextFile.txt', 'utf8');
console.log(data);
Copy File
Async:
Sync:
fs.copyFile(src, dest, callback)
Sync:
fs.copyFileSync(src, dest)
Examples
Asynchronous:
Copy file in same directory:
Synchronous:
Copy file in same directory:
Copy file to different directory:
Copy file in same directory:
fs.copyFile('myfile.txt', 'myfileCopy.txt', (err) => {Copy file to different directory:
if (err) throw err;
});
fs.copyFile('myfile.txt', 'src/myfile.txt', (err) => {
if (err) throw err;
});
Synchronous:
Copy file in same directory:
fs.copyFileSync('myfile.txt', 'myfileCopy.txt');
Copy file to different directory:
fs.copyFileSync('myfile.txt', 'src/myfile.txt');
Delete File
Async:
fs.unlink(path, callback)
Sync:
fs.unlinkSync(path)
Examples
Asynchronous version:
Synchronous version:
Remove all files in a directory:
fs.unlink('myTextFile.txt', (err) => {
if (err) throw err;
});
Synchronous version:
fs.unlinkSync('myTextFile.txt');
Remove all files in a directory:
fs.readdirSync('src').forEach((filename) => {
fs.unlinkSync(`src/${filename}`);
});
Directories
Read directory
- Returns array of all file and directory names in the given path.
- Async:
fs.readdir(path[, options], callback)
- Sync:
fs.readdirSync(path[, options])
Examples
Asynchronous version:
Synchronous version:
fs.readdir('.', (err, files) => {
if (err) throw err;
console.log(files);
});
Synchronous version:
const files = fs.readdirSync('.');
console.log(files);
Make directory
- Async:
fs.mkdir(path[, options], callback)
- Sync:
fs.mkdirSync(path[, options])
- Option:
{ recursive: true }
to add directories recursively (e.g., "src/data") - If directory already exists it returns an error. To prevent this, check if it exists first.
Examples
- Asynchronous version. First check if the srs directory exists. If not create the directory:
if (!fs.existsSync('src')) {
fs.mkdir('src', (err) => {
if (err) throw err;
console.log('directory created');
});
}
- Synchronous version.
fs.mkdirSync('src')
- Option: create the src and nested data directory recursively.
fs.mkdirSync('src/data', { recursive: true })
Remove Directory
Async:
Sync:
fs.rmdir(path[, options], callback)
Sync:
fs.rmdirSync(path[, options])
Examples
Asynchronous version:
Synchronous version:
Remove all files in a directory then delete directory:
fs.rmdir('src', (err) => {
if (err) throw err;
});
Synchronous version:
fs.rmdirSync('src')
Remove all files in a directory then delete directory:
fs.readdirSync('src').forEach((filename) => {
fs.unlinkSync(`src/${filename}`);
});
fs.rmdirSync('src');
Rename or Move File or Directory
- Renames the file if the old and new directories are the same.
- Moves the file if the old and new directories are different.
- Async:
fs.rename(oldPath, newPath, callback)
- Sync:
fs.renameSync(oldPath, newPath)
Examples
Asynchronous version. Moves the file to the src directory and renames it as well.
Synchronous version. Renames the directory from "src" to "data".
fs.rename('myTextFile.txt', 'src/textFile.txt', (err) => {
if (err) { throw err; }
});
Synchronous version. Renames the directory from "src" to "data".
fs.renameSync('src', 'data');
StreamGo to video for this category
Stream Module
- Ref: Nodejs.org/api/stream
- A data stream is the transfer of data between two points.
- The stream module provides an API for working with data streams.
- I/O intensive modules like fs, http, and process.stdin/stdout inherit from the stream module giving them access to stream methods.
- Stream inherits from the Buffer and Events modules.
- Streams can be readable, writeable, or both (duplex).
Streams and Buffers
Explanation
Using the File System as an example:
- Input could be a large text file, image file, or video file.
- The file data loads as a stream of bytes that are temporarily accumulated in a buffer object in RAM memory.
- Node's core Buffer module manages this part behind the scenes.
- The buffer stores the bytes in an array. When the buffer's array reaches its maximum size it passes the data as a chunk to be processed for output (e.g., played as a video).
- The default buffer size is 64 KB (64 * 1024 bytes). 1 byte holds 1 text char.
- The stream module inherits from the EventEmitter class.
- When a chunk of data is sent from the buffer a "data" event is emitted behind the scenes.
- A listener function needs to be in place to handle the data chunk on the "data" event.
- For large files, streaming has two advantages.
- It uses less memory than if you loaded the whole file at once.
- If it is a video file, the user can start watching the video before it is fully loaded.
Read a file without Streaming
const fs = require('fs'); fs.readFile('myFile.txt', 'utf8', (err, data) => { if (err) return console.error(err.message); console.log(data); })
Explanation
- This reads the myFile.txt text file and logs it to the console.
- The fs.readFile() method reads the whole file from the computer disk into RAM memory.
- It buffers the entire file regardless of size before invoking the callback function.
Read Stream
Read stream from the File System:
const fs = require('fs');
- Create a read stream object:
fs.createReadStream(path[, options])
const readStream = fs.createReadStream('./hugeFile.txt', 'utf8');
- Set the encoding option to 'utf8' for text, otherwise it returns a buffer object.
- When a data chunk is sent it emits a data event. Add listener with callback:
readStream.on('data', (chunk) => { /* Handle chunk data. */ });
- To only handle an event the first time it occurs, use the once() method.
readStream.once('data', (data) => { /* Handle event once */ });
- The end event occurs when the stream has completed.
readStream.on('end', () => { /* Handle end of stream */ });
- Listen for the error event to handle errors.
readStream.on('error', (err) => { /* Handle error */ });
Example: stream data from a large text file.
Read text from a file named hugeFile.txt.
// readstream.js
const fs = require('fs');
const readStream = fs.createReadStream('hugeFile.txt', 'utf8');
readStream.once('data', () => {
console.log('Start the data stream.');
});
readStream.on('data', (chunk) => {
console.log('\nPrint new chunk:\n', chunk);
});
readStream.on('end', () => {
console.log('Data stream complete');
});
readStream.on('error', (err) => {
console.error(err.message);
});
Steps:
- Load the File System 'fs' module.
- Create a read stream object specifying the path.
fs.createReadStream(path[, options])
- Set the encoding option to 'utf8' or it will return a buffer object instead of text.
- When the buffer sends a data chunk it emits the "data" event.
- The once() method will execute the callback function the first time the event occurs.
- The on() method executes the callback function every time the event occurs.
- The "end" event is emitted when the stream has finished sending all the data.
- You need to listen for an "error" event to handle any errors.
Write Stream
Write stream to the File System:
const fs = require('fs');
- Create a write stream object:
fs.createWriteStream(path[, options])
const writeStream = fs.createWriteStream("./output.txt", "utf8");
- Path is the destination file (e.g., './output.txt'). Creates file if it doesn't exist.
- The encoding option default for the write stream is 'utf8' so you can leave it out.
- Write to the file.
writeStream.write('Data string');
- The data in the argument gets written to the file.
Use read stream and write stream together
- Readable streams work with writeable streams.
- Read data from the input.txt file then output it to a new file called output.txt.
// read-write-stream.js
const fs = require('fs');
const readStream = fs.createReadStream('hugeFile.txt', 'utf8');
const writeStream = fs.createWriteStream('output.txt');
readStream.on('data', (chunk) => {
console.log(`Chunk received: ${chunk.length} characters`);
writeStream.write(chunk);
});
- Run the file: node read-write-stream
Steps:
- Load the File System 'fs' module.
- Create a read stream object specifying the path.
- Set the encoding option to 'utf8' or it will return a buffer object instead of text.
- Create a write stream object specifying the path.
- The default encoding for write stream is 'utf8'.
- If the output.txt file doesn't exist it will be created.
- Stream inherits from the EventEmitter class so it has access to event methods.
- When the buffer sends a data chunk it emits the "data" event.
- Chain the on() method listening for the "data" event.
- The callback function executes when each chunk of data is received.
- It logs a message to the console.
- Then writes the chunk to the output.txt file.
Pipe method
Chain the read stream directly to the write stream.
const fs = require('fs');
const readStream = fs.createReadStream('hugeFile.txt', 'utf8');
const writeStream = fs.createWriteStream('output.txt');
readStream.pipe(writeStream);
Explanation
The final line
readStream.pipe(writeStream);
is a shortcut for:readStream.on('data', (chunk) => {
writeStream.write(chunk);
});
- The read stream object streams chunks of data that are piped to the write stream object which adds it to the output.txt file.
HTTPGo to video for this category
HTTP Overview
Ref: developer.mozilla.org/en-US/docs/Web/HTTPHypertext Transfer Protocol (HTTP) definition
Hypertext Transfer Protocol (HTTP):
- is an application-layer protocol for transmitting hypermedia documents, such as HTML.
- is designed for communication between web browsers and web servers, but it can also be used for other purposes.
- follows a classical client-server model. Client opens a connection to make a request, then waits until it receives a response.
- is a stateless protocol. The server does not keep any data (state) between two requests.
- is often based on a TCP/IP layer.
- TCP/IP (Transmission Control Protocol/Internet Protocol) is the basic communication language or protocol of the Internet. It can also be used as a communications protocol in a private network (either an intranet or an extranet).
HTTP Request-Response Cycle
Request-Response Cycle steps, the Request Message, the Response Message.
HTTP Request-Response Cycle:
- A client (a browser) sends an HTTP request to a server over the internet.
- The web server receives the request.
- The web server application processes the request, getting files, possibly data from a database.
- The server returns an HTTP response (output) to the browser.
- The client (the browser) receives the response and processes it (e.g., displays an HTML page).
The Request Message:
- The request message is a stream of data from the client to the server.
- Starts with a Request line which contains:
- Request method: GET, POST, PUT, PATCH, DELETE.
- URL: the host (e.g., example.com) and path (e.g., /about).
- Protocol: HTTP or HTTPS.
- Request Headers containing additional info about the request.
- Optional Request Body:
- If the request is a form submission then it will send the form data.
- POST requests add new data.
- PUT or PATCH requests update existing data.
The Response Message:
- The server responds to the request with a response message. A stream of data from the server to the client.
- It starts with a Status line with the status code and reason message.
- 2xx success, 3xx redirect, 4xx client error, 5xx server error.
- Response Headers: includes type of content sent (e.g., HTML, JSON, CSS).
- Optional Response Body: The data sent back (e.g., HTML document, image, CSS).
HTTP Response Status Codes
- Ref: developer.mozilla.org/en-US/docs/Web/HTTP/Status
- HTTP responses include a status code and corresponding status message.
console.log(res.statusCode);
Logs the response object's statusCode property.
Status Code Partial List
Grouped by class (Info, Success, Redirect, Client Error, Server Error).
Includes Status Code and the corresponding message, and a description.
- Informational responses (100–199)
- Successful responses (200–299)
- 200 OK - The request has succeeded.
- 201 Created - POST or PUT request succeeded and a new resource created.
- 204 No Content - The action is successfully completed and no further info is to be supplied. Can use for a successful delete request.
- Successful responses by HTTP Request method:
- GET: 200
- POST: 201
- PUT: 200 update success, include data or a message. 204 indicates update success without sending back data or a message. 201 request was successful and created a new record.
- DELETE: 200 delete success, include a success message. 204 indicates success without sending back a message.
- Redirects (300–399)
- 301 Moved Permanently - Requested URL has been changed permanently. The new URL is given in the response.
- 302 Found - Requested URI has been changed temporarily. The original URI should be used by the client in future requests.
- 307 Temporary Redirect - Same as 302, but specifically specifies that the HTTP method must not change.
- 308 Permanent Redirect - Same as 301, but specifically specifies that the HTTP method must not change.
- Client errors (400–499)
- 400 BadRequest - Server could not understand request due to invalid syntax.
- 401 Unauthorized - Client must be authenticated before getting the requested response.
- 403 Forbidden - Client is known to the server but does not have access rights to the content.
- 404 NotFound - Server can not find requested resource. In the browser, this means the URL is not recognized.
- 422 UnprocessableEntity - Request content type and syntax are ok but the server was unable to process the contained instructions. Client should modify the request.
- Server errors (500–599)
- 500 InternalServerError - The server has encountered a situation it doesn't know how to handle.
Http Node Module
- Node.js includes http and https core modules.
- Ref: Nodejs.org Guides: http | Nodejs.org/api/http
- A Web Server is a software application which handles HTTP/HTTPS requests.
- The http module creates a web server serving HTTP requests.
- The https module serves requests from the secure HTTPS protocol.
- Express builds on these modules for its MVC framework.
Basic web server with one route
const http = require('http');
const server = http.createServer((req, res) => {
if (req.method === 'GET' && req.url === '/') {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('You are on the home page.');
}
});
server.listen(3000);
Explanation
- Load the http module with require().
- Create a server object using the createServer() method.
- The server object listens for requests, processes them, and sends the response.
- The http module inherits from Stream and EventEmitter classes so the server object uses streams and events.
- Listen for the Request:
- When an HTTP request is received, a connection must first be established.
- The
server.listen(port)
method asynchronously listens for requests. - In development include the port option, with a valid port such as 3000.
- When a request is received the following occurs behind the scenes.
- An TCP connection is established and the connection event is emitted. TCP is the protocol used for exchanging messages over the internet.
- On a connection event, the listener function reads the request, creates a request object, and emits a request event.
- The server object is listening for the request event.
- Handle the Request:
- createServer() takes the requestListener function as it's argument:
http.createServer([options][, requestListener])
- When the request event occurs this requestListener function executes.
- It has two parameters. The request object and the response object.
- Routing:
- Use the request object to get the request method and url.
- Here we are using an if statement to check if it is a GET request to the root path.
- Handle the Response:
- In each route block prepare a response.
- Write a header with the appropriate status code (200 for success) and the content-type.
- Then we send the data as the argument to the end() method. In this case it is just plain text.
- The end() method tells the server the message is ready to be sent.
Serving files
To serve files, load the fs module, create a read stream, and pipe it to the response.
if (req.method === 'GET' && req.url === '/about') {Serve a JSON file (for an api):
res.writeHead(200, {'Content-Type': 'text/html'})
fs.createReadStream('./about.html', 'utf8').pipe(res);
}
if (req.method === 'GET' && req.url === '/api/articles') {
res.writeHead(200, {'Content-Type': 'application/json'})
fs.createReadStream('./articles.json', 'utf8').pipe(res);
}
EventsGo to video for this category
Event Loop
Define synchronous, asynchronous, Explain diagram
- Synchronous (sync): Code is executed in sequence, line by line, one line at a time. Blocking: When a synchronous function is called, the program waits until the function returns its value before proceeding to the next line.
- Asynchronous (async): Function calls are made in sequence but the program doesn't wait for the result before moving on to the next line. Non-blocking: Instead, the async function's task is processed in the background. Event-driven: When complete it passes the result to a callback function which gets sent to the event loop for execution.
Explain Diagram:
- Ref: Nodejs.org/en/docs/guides/event-loop-timers-and-nexttick
- The JS Engine contains the call stack and a memory heap.
- It parses the JS code, converts it to machine code, and executes it.
- To do this it creates a space in RAM memory to hold data objects (variables, function definitions, objects, arrays) using a heap data structure.
- Functions are placed on the call stack and executed. When the functions are executed, all the data is written to the heap and the stack references the memory addresses when executing the code. When the code finishes executing, the JS Garbage Collector removes the data from memory.
- The call stack operates on a Last-In-First-Out (LIFO) basis. So if the function on the stack calls another function, that will get placed on top of the stack and executed first.
- Functions in the call stack are executed synchronously. Other code is blocked from running until it is complete. Once complete it is removed from the stack and the function below it is executed. This continues until the stack is empty.
- I/O operations: Managed by Node's libuv library using a design called the Reactor pattern.
- I/O operations such as accessing the file system, network, timer, or a database generally need to be processed asynchronously for performance reasons.
- When a function on the call stack calls an I/O-related function, it passes a callback function argument (or creates a Promise object) to handle the result. It is then immediately removed from the call stack (so it doesn't block).
- Node passes the I/O task to be processed in parallel by the operating system or in some cases by a pool of threads.
- Node modules inherit from the Event module which they use to emit an event when an I/O task is complete.
- Node listens for the event. When emitted the callback function is added to the end of the callback queue with the result.
- Like the browser, Node.js runs an event loop. The event loop monitors the call stack which runs synchronously. When the call stack is empty the event loop checks the callback queue for the next callback function. If there is one it places it on the call stack to be executed.
- The Callback Queue operates on a First-In-First-Out basis. If there are multiple callback functions in the queue it takes the oldest one first.
- When the callback queue is empty, the event loop continually monitors it for a new callback.
Asynchronous function calls
- Include a callback function as the last argument (by convention) in the function call.
- The task is processed asynchronously behind the scenes.
- When the task completes Node calls the callback function:
- By convention, the first arg is for the error object. If no error, the first arg is null.
- If task returns data, the second arg is the data returned.
const fs = require("fs");
fs.readdir(".", (err, files) => {
if (err) { throw err; }
console.log(files);
});
Step by step explanation
- The above example imports the Node fs (File System) module. Ref: Nodejs.org:api
- It calls the readdir method which returns an array of all file names in the given directory.
Method syntax: fs.readdir(path[, options], callback)
- Node passes this task off to the operating system. When it is complete it passes Node the result or an error.
- If there is an error Node calls the callback function passing in the error object. The if statement checks for an error, then throws the error.
- If there is not an error Node calls the callback with a null value for err, and the files array as the second arg. The function then logs the files array to the console.
Events Module
- Ref: Nodejs.org/api/events
- Node's Events module drives its asynchronous event-driven architecture.
- Consists of the EventEmitter class with methods for emitting and listening for events.
- Events module is used in:
- Node's own core modules such as fs, http, and process.stdin/stdout.
- Third party npm packages that involve I/O tasks such as querying a database.
- Can be used in your own modules if you have I/O tasks.
Three basic steps for adding asynchronous events to a class
Full Example
// 1) Create instance of a class that inherits from EventEmitter.
const EventEmitter = require('events');
class Chat extends EventEmitter {}
const session = new Chat();
const EventEmitter = require('events');
class Chat extends EventEmitter {}
const session = new Chat();
// 2) Register listener functions on events.
session.once('begin', function() {
console.log('\nBegin Chat Session...');
});
session.once('begin', function() {
console.log('\nBegin Chat Session...');
});
session.on('send', function(participant, msg) {
console.log(`${participant}: ${msg}`);
});
console.log(`${participant}: ${msg}`);
});
session.on('error', (err) => {
console.error(err.toString());
});
console.error(err.toString());
});
// 3) Emit events
session.emit('begin');
session.emit('send', 'Sheena', 'Can you explain the Event Loop?');
session.emit('send', 'Joey', 'Yes');
session.emit('send', 'Sheena', 'Will you?');
session.emit('send', 'Joey', 'No');
session.emit('error', new Error('Message not sent.'));
session.emit('begin');
session.emit('send', 'Sheena', 'Can you explain the Event Loop?');
session.emit('send', 'Joey', 'Yes');
session.emit('send', 'Sheena', 'Will you?');
session.emit('send', 'Joey', 'No');
session.emit('error', new Error('Message not sent.'));
1) Create an instance of the EventEmitter class:
const EventEmitter = require('events');
const emitter = new EventEmitter();
- Or create instance of class that inherits from EventEmitter:
const EventEmitter = require('events');
class ClassName extends EventEmitter {}
const emitter = new ClassName();
Examples
- Create an instance of the EventEmitter class:
const EventEmitter = require('events');
const session = new EventEmitter();
- Or create instance of class that inherits from EventEmitter:
const EventEmitter = require('events');
class Chat extends EventEmitter {}
const session = new Chat();
2) Register one or more Listeners on an event:
Chain on() to emitter instance. Executes listener function every time event occurs.
- emitter.on(eventName, function([args]) { /* handle event */ }
Examples
- Register event listener with no argument:
session.on('send', function() {
console.log('Message was sent');
});
- With arguments:
session.on('send', function(participant, msg) {
console.log(`${participant}: ${msg}`);
});
- emitter.once(eventName, function([args]) { /* handle event */ }
Example
session.once('begin', function() {
console.log('Begin Chat Session...');
});
3) Emit an event
To emit an event, chain the emit() method to the emitter instance.
- emitter.emit(eventName[, ...args])
- Synchronously calls each listener registered on eventName, in the order registered, passing the supplied arguments to each.
- Returns true if the event had listeners, false otherwise.
Examples
- Emit event with no argument:
session.emit('begin');
- With arguments:
session.emit('send', 'Sheena', "Can you explain the Event Loop?");
session.emit('send', 'Joey', "Yes");
Error events
Emit an error event with a corresponding error listener.
emitter.on('error', (err) => {
console.error(err.message);
});
emitter.emit('error', new Error('message'));
Example and more details
// 2) Register listener functions on events.
session.on('error', (err) => {
console.error(err.toString());
});
// 3) Emit events
session.emit('error', new Error('Message not sent.'));
- Emit an error event passing an Error object as the second argument.
- When creating the Error object, you can pass in a message as the argument.
- You can just log the message by chaining it to the error object passed in: err.message.
- err.toString() will display both the error class name and message.
- err.stack is a string containing:
- The error class name and the error message.
- A series of stack frames (each line beginning with "at") starting at the point in the code where the Error was instantiated, tracing backwards.
- err.stack is the default display for the err object.
- If you throw an error it will print the stack property and exit the Node process.
session.on('error', (err) => { throw err; });
- If you emit an error event but don't have an error listener, it will be thrown, a stack trace printed, and the Node.js process will exit.