4. Node JS

Terminal

  • Shell program running on a terminal
  • Bash an emulator for running Unix shell on Windows

Commands

  • ls list director
  • pwd print working directory
  • cd change directory
  • cd.. back one level
  • absolute path starts with / i.e.: cd /Users/Documents and cd ../../Documents
  • mkdir make directory
  • man manual: man ls
  • touch make new file
  • rm FileName remove file
  • rmdir FolderName remove directory (only if it is empty)
  • rm -rf FolderName delete recursive and force (when folder is not empty)

Node JS

A Javascript runtime (run Javascript outside the browser).

  • Web Servers
  • Command Line Tools (npm)
  • Native apps
  • node FileName.js execute file

Process

The process object provides information about, and control over, the current Node.js process.

  • process.argv returns an array containing the command-line arguments passed when the Node.js process was launched. The first element will be process.execPath. See process.argv0 if access to the original value of argv[0] is needed. The second element will be the path to the JavaScript file being executed. The remaining elements will be any additional command-line arguments.
  • process.cwd() returns the current working directory of the Node.js process.
const fs = require('fs');

//console.log(fs);
fs.mkdir('apple', {recursive: true}, (err) => {
    console.log("in the callback")
});

fs.mkdir.mkdirSync('Cats');

Get user input:

const fs = require('fs');
const folderName = process.argv[2]

fs.mkdir.mkdirSync(folderName);

Then from the commandline we type: node index.js MyFolderName

Modules

const add = (x,y) => x+y;
const square = x => x*x;
const PI = 3.14159;

module.exports.add = add;
module.exports.PI = PI;
const math = require('./math');

Requiring directory

shelter index.js //main file for this directory blue.js red.js green.js

#blue.js
module.exports = {
    name: 'blue',
    color: 'orange'
}
const blue = require('./blue')
const red = require('./red')
const green = require('./green')

const allColors = [blue, red, green]
module.exports = allColor
const colors = require('./shelter') //looks for the index.js file

npm

  • npm i packageName install in the local directory
  • npm i -g packageName install global packages and then npm link packageName
  • npm init creates a package.json file in the folder
  • npm i installs all dependencies from package.json

Express

  • library: include in your code, you decide when to uses
  • framework: provide the structure for the application, you follow its rules
  • routes are matched in order
const express = require("express")

const app = express()

//match every single request
// app.use((req, res)=>{
//     console.log("new request");
//     res.send("hello this is a response")
// })

app.get('/cats', (req, res) =>{
    res.send("MEOW")
    console.log("cat request");
})

app.get('/dogs', (req, res) =>{
    res.send("BAU")
    console.log("dog request");
})

app.get('/', (req, res) =>{
    res.send("this is the homepage")
    console.log("homepage");
})

app.post('/cats', (req, res) => [
    res.send("this is a post request")
])

app.listen(3000, () => {
    console.log("listening on port 3000")
})

Define a pattern

app.get('/r/:subreddit/:postId', (req, res) =>{
    const {subreddit, postId} = req.params;
    res.send(`post id: ${postId} on ${subreddit} subreddit`)    
})

Query strings

app.get('/search', (req, res)=>{
    //search?q=dog
    const {q} = req.query; 
    res.send(`Hi ${q}`);
})

Autorestart Server

  • npm i -g nodemon
  • nodemon index.js

Creating Dynamic HTML With Templating

Templating

  • EJS embedded javascript
mkdir Templating
cd Templating
npm init -y
npm i express
touch index.js
  1. Create server
const express = require('express');
const app = express();

app.get('/', (req, res) =>{
    res.send("HI THERE");
})

app.listen(3000, () => {
    console.log("Listening on port 3000")
})
  1. Load ejs:
  • npm i ejs install the module
  • app.set('view engine', 'ejs');
  • ejs looks for .ejs files by default in /views mkdir views touch views/home.ejs
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>The Home Page</h1>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Corporis id eum cumque facere, nostrum quasi commodi, maiores perspiciatis incidunt totam vero iste et reiciendis aliquid sapiente est magnam laudantium maxime?</p>
    <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. A aspernatur id nemo architecto, ratione assumenda officia hic ipsam corrupti doloribus, enim adipisci nisi fugit atque nam quia vero minima perferendis!</p>
</body>
</html>
  1. Instead of sending back a text, we can send back a file
app.get('/', (req, res) =>{
    res.render('home.ejs');
})
  1. Make the views folder relative to the path
    const path = require('path')
    app.set('views', path.join(__dirname, '/views'))
    

Interpolation Syntax

  • Syntax for HTML <h1>The Home Page <%= 4+5+1 %></h1>

  • Instead of embedding JS in the HTML, pass an object

<h1>Your random number is: <%= rand %> </h1>

app.get('/rand', (req, res) =>{
    const num = Math.floor(Math.random()*10)+1;
    res.render('random', {rand: num})
    //res.render('random', {num}) i.e. num: num    
})
  • Route parameters
app.get('/r/:subreddit', (req, res)=>{
    const {subreddit} = req.params;
    res.render('subreddit', {subreddit});
})
  • Conditionals
    <h1>Your random number is: <%= num %> </h1>
    <%  if (num%2 ===0){ %>
        <h2>This is an even number!!</h2>
        <% } else { %> 
        <h2>This is an odd number!!</h2>
    <% } %> 
<h3><%= num%2===0 ? 'Even' : 'Odd' %> </h3>
  • Loops
    <ul>
    <% for (let cat of cats) {%> 
        <li><%= cat %> </li>
    <% } %>
    </ul>    

Example

  1. Load the data const redditData = require('./data.json')

  2. Get the data from json
    app.get('/r/:subreddit', (req, res)=>{
     const {subreddit} = req.params;
     const data = redditData[subreddit]    
     if (data){
         res.render('subreddit', {...data});
     }else{
         res.render('notfound', {subreddit});
     }
    })
    
  3. Display the content ```html

Browsing The <%= name %> subreddit

<%= description %>

Total Subscribers <%= subscribers %>


<% for (let post of posts){ %>

<%= post.title %> - <%= post.author %>

<% if (post.img){ %> <% } %>
<% } %>

### Serving static assets

1. Create a folder called public to store all the static assets
2. Load the content of the folder: `app.use(express.static(path.join(__dirname, '/public')))`
3. Use the stylesheet in the templates: `<link rel="stylesheet" href="/style.css">`

### Bootstrap + Express

1. Download and copy `bootstrap.min.css`, `bootstrap.min.js` and `jquery.js` in the public folder
2. Load them in `index.js`
```csharp
app.use(express.static(path.join(__dirname, '/public')))
  1. Load them in the template
     <link rel="stylesheet" href="/css/bootstrap.min.css">
     <script src='/js/bootstrap.min.js'></script>
     <script src='/js/jquery.js'></script>
    
  2. Apply style to content ```html
Written on August 1, 2021