Learning NodeJS Part 3: Getting Started
Tags: node, beginners
Published: 2021-01-03 21:33:28

*In late fall of 2020, I went on a mission to better understand Node. I wanted to improve the way I use it, how I might be able to use more of its features, and moreover grow my front end knowledge to full stack. This series includes the notes I've compiled from my learnings over at [The Odin Project](https://www.theodinproject.com/courses/nodejs). The lessons also include general web concepts necessary to better work with Node.*

----

Let's look at some common Node jargon, and what it means to develop these features in a Node environment. 

## **Modules**
### What is a module?
Think of modules as libraries - a set of functions you can choose to include in your app.

### How does one create and use modules?
To create your own module, use `exports` to make properties and methods available outside of the module file. The following returns the current date and time:

```javascript
exports.myDateTime = function () {
  return Date();
};
```
Once you've created a module, to actually use the module in a different JS files we utilize the `require()` function, passing to it the name of the desired module. You also use this for including modules that are built-in:

`var myDateTime = require('myDateTime');`

Now, let's practice making modules as well as using existing ones.

### Creating and Using a Module
Create a `square.js` module with a method called `area()`, then include `area()` in a new file (`example.js`) to calculate the area of a square with a width of 4.

```javascript
// square.js 
exports.area = function(width) { return width * width; };

// OR

module.exports = {
  area: function(width) {
    return width * width;
  }
};
```

```javascript
// example.js
const square = require('./square'); 
console.log('The area of a square with a width of 4 is ' + square.area(4));
```

### Using the HTTP Module: Set up a basic web server with Node 

```javascript
var http = require('http');

// The function passed into the http.createServer() method
// will be executed when someone tries to access the computer on port 8080
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.end('Hello World!');
}).listen(8080);
```
What's happening here? This code creates a server and says “any time we get a network request, run this callback function”. The function happens to respond with the text *Hello World!* So if you save this code to a `.js` file, run it using `node name-of-file.js` and navigate to `http://localhost:8080/` on your browser of choice, you will see *Hello World!* on your screen.

### Using the URL Module: Parse a url address and split it into readable parts

What would this take?
1. We first need to include the url module. 
2. Then, store in a variable the address we would like to parse along with it's parsed version in a third variable.
3. You can see what the parsed version gives us in the 3 `console.log()` statements below.
4. Lastly, we can query through the last bits of the url to return whatever it is we are looking for.

Let's see this in action:
```javascript
var url = require('url');
var adr = 'http://localhost:8080/default.htm?year=2017&month=february';
var q = url.parse(adr, true);

console.log(q.host); //returns 'localhost:8080'
console.log(q.pathname); //returns '/default.htm'
console.log(q.search); //returns '?year=2017&month=february'

var qdata = q.query; //returns an object: { year: 2017, month: 'february' }
console.log(qdata.month); //returns 'february'
```

Now that we know how to parse a url address and in the section before that we learned how to set up a basic webserver in Node, let's combine the two.

### Serve a requested file to the client

Let's again break down what these steps would look like:
1. Create two html files, `summer.html` and `winter.html`
2. Put some basic html into both files, ensuring they both consist of different content
3. Within that same folder, create a `.js` file requiring the http, url and fs modules
4. Using these modules to create a server, parse through the url and open the requested file to the client. (`http://localhost:8080/summer.html` should render the contents of your `summer.html` page and `http://localhost:8080/winter.html` should render the contents of your `winter.html` page.)
5. Be sure to throw a 404 error if anything goes wrong  

```javascript
var http = require('http');
var url = require('url');
var fs = require('fs');

http.createServer(function (req, res) {
  var q = url.parse(req.url, true);
  var filename = "." + q.pathname;
  fs.readFile(filename, function(err, data) {
    if (err) {
      res.writeHead(404, {'Content-Type': 'text/html'});
      return res.end("404 Not Found");
    } 
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.write(data);
    return res.end();
  });
}).listen(8080);
```

## **CRUD with Node**
Now, onto creating, reading, updating and deleting files with Node.

### Let's say we wanted our basic server to read from some sample file (say `demofile1.html`) and return to the client (write on the page) whatever is in `demofile1.html`:
```javascript
var http = require('http');
var fs = require('fs');

http.createServer(function (req, res) {
  fs.readFile('demofile1.html', function(err, data) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.write(data);
    return res.end();
  });
}).listen(8080);
```

### Write a program that uses the `appendFile()` method to append 'Hello content!' to a new file named `mynewfile1.txt`.
```javascript
var fs = require('fs');

fs.appendFile('mynewfile1.txt', 'Hello content!', function (err) {
  if (err) throw err;
  console.log('Saved!');
});
```

### What is the difference between appendFile(), open(), and writeFile()?
- `appendFile()` adds specified content to the end of a file. If the file does not exist, the file will be created.
- `open()` takes a "flag" as the second argument, if the flag is "w" for "writing", the specified file is opened for writing. If the file does not exist, an empty file is created.
- `writeFile()` replaces the specified file with content (if the file exists). If the file does not exist, a new file containing the specified content, will be created.

### Write a program that deletes a file, say `mynewfile1.tst`
```javascript
var fs = require('fs');

fs.unlink('mynewfile2.txt', function (err) {
  if (err) throw err;
  console.log('File deleted!');
});
```

## **Packages**
### What are packages?
NPM packages contain all the files you need for a module. Think of them as add-ons to your project to give it extra abilities or avoid having to write some functionality from scratch.

### Wait - what's the difference between modules and packages?
A package is a file or directory that is described typically by a `package.json` file. A module is any file or directory in the `node_modules` directory of a project that can be loaded in by Node. Since modules are not required to have a `package.json` file, not all modules are packages. Only modules that have a package.json file are also packages.

### How do you use an NPM package?
1. NPM is already installed once you install Node
2. Install package of your choice via `npm install name-of-package`
3. Include the package just like you would with any module: `var package = require('package-name');`

## **Events**
We briefly discussed events in part 1 of this series. To refresh:

>Every action on a computer is an event. It could be a network request that triggers something else or someone trying to access a port on a server.

### How do we interact with events in Node, i.e. how does one create, fire and listen for events?

1. Include the Events module - this allows you to create, fire and listen for events: `var events = require('events');`
2. All event properties and methods are an instance of an EventEmitter object, so to access them you have to create an EventEmitter object: `var eventEmitter = new events.EventEmitter();`
3. Assign event handlers to your own events with the EventEmitter object. To fire an event, use `emit()`

For example, suppose I wanted a `scream` event to fire whenever some action occurred:

```javascript
var events = require('events');
var eventEmitter = new events.EventEmitter();

//Create an event handler:
var myEventHandler = function () {
  console.log('I hear a scream!');
}

//Assign the event handler to an event:
eventEmitter.on('scream', myEventHandler);

//Fire the 'scream' event:
eventEmitter.emit('scream');
```

----

Now that we're more familiar with some of Node's powers, let's move on to the way Node is actually used in most scenarios - via a framework.