nodejs

home

Contents

what is nodejs

Why to use nodejs

Nodejs First Look

Express First Look

        console.log("enter app.js");
        var express = require("express");
        var app = express();
        app.get("/", function(req, res){
            res.end("welcome, express");
        });
        app.listen(3000, function(){
            console.log("the server is listening port 3000")
        });
            
res.end("<h1>hello in html</h1>") // test, In ARC, just enter url. // In the response area, you see the result, <h1>hello in html</h1> // h1 tags and the text are data // The web client has to further to process and render it.
        var msg = "passing data";
        app.get("/", function(req, res){
            res.end(`The meesage is ${msg}`);
            console.log(`method is ${req.method}`);   
        });
            
            var jsonData = {"name": "Tairo", "color": "brown"};
            var strData = JSON.stringify(jsonData);
            app.get("/", function(req, res){
                res.end(`${strData}`);
            });
            

REST POST

                // app.js
                console.log("enter app.js      test 1");

                var express = require("express");
                var app = express();

                app.post("/", function(req, res){
                    res.end("post completed");
                });

                app.listen(3000, function(){
                    console.log("the server is listening port 3000")
                });
            
                // code 
                app.post("/", function(req, res){
                var msg = "hello";
                console.log(`msg = ${msg}`);
                console.log(`req.url = ${req.url}`);
                console.log(`req.method = ${req.method}`);
                console.log(`req.body = ${req.body}`);
                res.end("post completed");
                });
                // test result         
                C:\peter9\ExpressApp4917>node app
                enter app.js      test 3
                the server is listening port 3000
                msg = hello
                req.url = /
                req.method = POST
                req.body = undefined
                // code
                var bodyParser = require('body-parser');
                app.use(bodyParser.json());

                app.post("/", function(req, res){
                    console.log(req.body);
                    res.json(req.body);
                });
            

Route

        demo 1
        var express = require('express');
        var app = express();

        app.get('/', function(req, res){
            res.send("in route root")
        });

        app.get('/products', function(req, res){
            res.send("in route products")
        });

        var server = app.listen(3000, function(){
            console.log("Listening on port 3000, app4_route, 7:10");
        });
            
        demo 2 --- passing data from url to route dog
        var express = require('express');
        var app = express();
        
        app.get('/dog/:name?/:color?', function(req, res){
            var name = req.params.name;
            var color = req.params.color;
        
            res.send(
                "name=" + name + "  color=" + color
            )
        });

        var server = app.listen(3000, function(){
          console.log("Listening on port 3000, 7.17");
        });
            
demo 3 --- one route with get and post
        // step 1.1   code api-get app.js as below
        var express = require('express');
        var app = express();

        app.get('/', function(req, res){
            var jsonDog = {"name": "Tairo", "color": "brown:"};
            res.json(jsonDog);
        });

        var server = app.listen(3000, function(){
          console.log("Listening on port 3000, app42_route, 7:52");
        });
        // step 1.2    open command window, navigate to the app folder
        // step 1.3.1  not rest test,open the browser, see the result from api get. 
        // step 1.3.2  rest test, in the chrome browser, click menu apps, then click ARC
        // step 1.3.2x     enter url
        // step 1.3.2y     select GET, not need to set Content-Type, click button send, to see the result in the reponse section
        // comment: A client type - REST or not, depends how it calls in the client.   
            
    // step 2.2  in application js file, insert code after app.get
    
        var bodyParser = require("body-parser");
        app.use(bodyParser.json());
        console.log("after creating bodyParser.json() middleware");

        app.post('/', function(req, res){
            console.log(" in post api");
            var name = req.body["name"];
            var color = req.body["color"];
            console.log(`
                name=${name}    color=${color}
            `);
            res.json(req.body);
        });
    
    // step 2.3  run the server again, node app.js,  you see the log before the post.
    // step 2.4  open browser chrome, menu apps, select ARC application
    // step 2.5   set url to localhost:3000 
    //            set Content-Type to applicaiton/json
    //            set Raw payload to {"name": "Emi", "color": "white}
    //            click button send
    // step 2.6   in the ARC's response area, you see the data
    // step 2.7   in the command window, you see the log from post.
    //                and the contents of the post json items
            

Routing Code Partition

        // step 1: Create a router file named birds.js in the app directory, with the following content:
        
        var express = require('express')      // mini app
        
        var router = express.Router()

        // middleware that is specific to this router
        router.use(function timeLog (req, res, next) {
          console.log('Time: ', Date.now())
          next()
        })
        // define the home page route
        router.get('/', function (req, res) {
          res.send('Birds home page')
        })
        // define the about route
        router.get('/about', function (req, res) {
          res.send('About birds')
        })
        
        module.exports = router   // module is nodejs global variable
                                  // exports is one of its property
        
        // step 2:  load the router module in the app:
        var birds = require('./birds')

        // ...
        
        app.use('/birds', birds)       // binding the app and the import module
        

        // step 3:  tests
        The app will now be able to handle requests to /birds and /birds/about,
        as well as call the timeLog middleware function that is specific to the route.

            

Folder public

demo 1 --- rendering a html file, not inside a route
        var express = require('express');
        var app = express();

        console.log("location-1, before using middle ware static");
        app.use(express.static('public'));

        app.get('/', function(req, res){
            console.log("inside route route");
            res.send("enter route route")
        });

        var server = app.listen(3000, function(){
          console.log("Listening on port 3000, test 3:10");
        });
            


demo 1x --- rendering a html file, inside a route
        // no need middleware public
        var path = require("path");

        app.get('/', function(req, res){
            res.sendFile(path.join(__dirname + '/public/page1.html'));
        });
        // test with localhost:3000
        // not much pratical purpose, just use demo 1 pattern like post client in the same site
            


demo 1y --- rendering a html file, with css and js // html file ------------------------------------------ <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="css/style2.css"> </head> <body> <h1>My First Heading</h1> <p>My first paragraph. 11:04</p> <button onclick='sayHello()'>click me</button> <script src="js/MyJSFile.js"></script> </body> </html> // css file -------------------------- body { background-color: lightgray; } h1 { color: white; text-align: center; } p { font-family: verdana; font-size: 36px; } // js file ----------------------------- function sayHello(){ alert("hello world"); } // test: localhost:3000/page1.html see the style and js action

demo 1z --- accessing css file in a different folder
         -folder structure
         -public
             products/page2.html
             css/style2.css
         -test:   localhost:3000/products/page2.html
         -using route root
         -theme: accessing css file in a different folde
             
// page2.html code <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="../css/style2.css"> </head> <body> <h1>products</h1> <p>7:29</p> </body> </html>
        // application js code
        var express = require('express');
        var app = express();
        app.use(express.static('public'));
        app.get('/', function(req, res){....
            


demo 2 ----json data from public and from a regular folder
        var express = require('express');
        var app = express();

        // for public, no need folder names,  public and data
        var myJson = require('./dog.json');
        console.log(myJson["name"]);

        // for not public, the folder name is needed
        var dog2 = require('./folder1/dog2.json');
        console.log(dog2["color"]);
            
app.get('/', function(req, res){ res.send(` // back tick <h2>data from json</h2> <p>${dog2["color"]}</p> `) // back tick }); var server = app.listen(3000, function(){ console.log("Listening on port 3000, 7.17"); });

Embedded Java Script

            // application js file
            var express = require('express');
            var app = express();

            app.use(express.static('public'));

            app.set('view engine', 'ejs');

            app.get('/', function(req, res){
                res.render("default2")
            });

            var server = app.listen(3000, function(){
              console.log("Listening on port 3000, test 8:05");
            });
            
// default.ejs <!DOCTYPE html> <html> <head> <link href="/css/style2.css" rel="stylesheet" type="text/css"> </head> <body> <h1>test css</h1> <p> 8:05</p> <button onclick='sayHello()'>click me</button> <script src="js/MyJSFile.js"></script> </body> </html> // css file body { background-color: lightgray; } h1 { color: white; text-align: center; } p { font-family: verdana; font-size: 36px; } //js file function sayHello(){ alert("hello world"); }
              // replace the res.render method as below
              res.render("default", 
               {
                   title: 'Wiwi  favorite fruits',
                   fruits: ['banana', 'pineapple', 'apple']
               })
             
// replace the ejs as below <!DOCTYPE html> <html> <body> <h1><%= title %></h1> <ul> <% for (var i = 0; i < fruits.length; i++){ %> <li> <%= fruits[i] %> </li> <% } %> </ul> </body> </html> notes: <%= %> is used to render a expression. <% %> is for javascript code.

using pug(jade) template engine

              res.render("default", 
               {
                   title: 'Wiwi  favorite fruits',
                   fruits: ['banana', 'pineapple', 'apple']
               })
             
                doctype html
                html
                  head
                    link(href='/css/style2.css', rel='stylesheet', type='text/css')
                  body
                    h1 #{title}            expression
                    ul
                        each val in fruits code
                            li= val        code
                    button(onclick='sayHello()') click me
                    script(src='js/MyJSFile.js')
             

Posting Data with HTML Form

        // application js file
        var express = require('express');
        var app = express();

        app.use(express.static('public'));

        
        var bodyParser = require('body-parser');
        app.use(bodyParser.urlencoded({extended: false}));
        

        app.get('/', function(req, res){
            console.log("enter get 10:50");
            res.send("from get  1:54");
        });

        
        app.post('/', function(req, res){
            var fn = req.body.firstname;
            var ln = req.body.lastname;
            console.log("enter post 1:54 pm ");
            console.log(fn + "," + ln);  
            res.send("post data have been received.");
        });
        

        var server = app.listen(3000, function(){
          console.log("Listening on port 3000, 1:54");
        });
             
// form.html <!DOCTYPE html> <html> <body> <form action="/" name="myForm" method="post"> First name:<br> <input type="text" name="firstname" value="Mickey"> <br> Last name:<br> <input type="text" name="lastname" value="Mouse"> <br><br> <input type="submit" value="Submit"> </form> </body> </html>

--- Part 3.1, pug form, data from a javascript object in the pug ---

        // main code in applcation js file
        app.set('view engine', 'pug');
        app.get('/', function(req, res){
            res.render('myForm2'); 
            // views/myForm2.pug
        })
        // code myForm2.pug as below
        - var fruits = ['apple', 'banana', 'melon', 'orange']  // javascript in pug
        doctype html
        html
          body
            form(action='/page2', method='post')
              select(name='fruit')
                each item in fruits
                  option(value=item) #{item}
              br
              br
              input(type='submit')
            

--- Part 3.2, pug form, data from the route in the server,    NOT inside the pug file ---

        // add a second function argument in res render, applcation js file
        res.render('myForm2',{fruits: ['apple', 'banana','melon', 'orange']})
        
        // remove one line of javascript in myForm2.pug as below 
        - var fruits = ['apple', 'banana', 'melon', 'orange'] 
            

--- Part 4.1 using ejs with html code only

        // main application js code 
        var bodyParser = require('body-parser');
        app.use(bodyParser.urlencoded({extended: false}));
        
        app.set('view engine', 'ejs');
        
        app.get('/', function(req, res){
            res.render('form2.ejs');
        });

        app.post('/', function(req, res){
            var fruit = req.body.fruit
            console.log("You select " + fruit);
            res.send('page2, post');
        });
        
---- views/form2.ejs 100% html ----- <!DOCTYPE html> <html> <body> <form action="/" name="myForm" method="post"> <select name="fruit"> <option value="apple">Apple</option> <option value="banana">Banana</option> <option value="melon">Melon</option> <option value="orange">Orange</option> </select> <br><br> <input type="submit"> </form> </body> </html>

--- Part 4.2 using ejs, data from its route

    // ----  js file, in the route, add data as the 2nd parameter for method render   ----
    res.render('form3.ejs', {myFruits: ["apple", "banana", "melon", "orange"]} );
        
---- views/form3.ejs -------- <!DOCTYPE html> <html> <body> <form action="/" name="myForm" method="post"> <select name="fruit"> <% for (var i = 0; i < myFruits.length; i++) { %> <option value="<%=myFruits[i]%>"><%=myFruits[i]%></option> <% } %> </select> <br><br> <input type="submit"> </form> </body> </html>

function, module, middleware

1.1 function

        var express = require('express');
        var app = express();
        
        function funcName(fn, ln){
            var name = fn + ", " + ln;
            return name;
        }
        
        app.get('/', function(req, res){
            var name = funcName("Tairo", "Kao");
            console.log(name);
            res.send(name);
        });

        var server = app.listen(3000, function(){
              console.log("Listening on port 3000, test 1");
        });
            

1.2    a javascript object can be a number, a string, even a function

        var fullName = function(fn, ln){
            return fn + ", " + ln;
        }

        app.get('/', function(req, res){
            // the function is accessible within this module
            var name = fullName("Emi", "Kao");
            console.log(name);
            ....
        });
            

1.3  create a function in a different js file

        // 1.3.1 under app folder, add a subfolder lib, then add this file
        //The file name is FullName.js
        var Dog = function(fn, ln){
            return fn + ", " + ln;
        }
        
        // module is a global variable
        // exports is module's build-in object
        // then, this module can be included in other js file
        module.exports = Dog 
        

        // 1.3.2 use the function in the application js file
        app.get('/', function(req, res){
            // the function is accessible within this module
            var dogName = require("./lib/FullName"); // dot means current directory.
            // dogName is a js object name, it is a function.
            var dog1 = dogName("Tairo","Kao");
            var dog2 = dogName("Emi", "Kao");   
            console.log(dog1);
            console.log(dog2);
            ....
        });
        

1.4  module examples

        // 1.4.1 module example - core modules, installed with nodejs  
        var util = require('util');     // module util for timestamp   
        util.log("Listening on port 3000");
        
        // 1.4.2 module examples - npm installation needed
        // They all have their usages

        // module express
        var express = require('express');    // module express
        var app = express();                 // use express() function
        app.use(express.static('public'));   // use express api
                                             // static is a method
                                             // see section folder public for detail
        app.get('/',   ){...};               // use express api

        // module ejs
            - It must be installed.
            - no need  ---  require 
            - need     ---  app.set('view engine', 'ejs');
        
            

1.5  middleware

The following code demonstrates express middleware features.

        // under folder lib, add the following file mm.js
        module.exports = function(req, res, next){
            console.log("enter mm.js");
            req.mydata2 = "do nothing ! from mydata2, assigned in shared middleware";
            next();
        }

        //  app.js
        var express = require('express');
        var app = express();

        app.use(function(req, res, next){
            console.log("enter the first local middleware");
            console.log(req.method);
            req.body = "data from req.body";
            req.mydata = "data from req.mydata";   // custom data
            next();
        });

        var mw = require('./lib/mm');
        app.use(mw);

        app.use(function(req, res, next){
            console.log("enter the second local middleware");
            console.log(req.body);
            console.log(req.mydata);
            next();
        });


        app.get('/', function(req, res){
            res.send(req.mydata2);
        });


        console.log("after app.get");

        app.use(function(req, res){
            console.log("You will not see me here after a response");
        });

        var server = app.listen(3000, function(){
              console.log("Listening on port 3000");
        });

            

Expressjs.com

Events

        // scenario: One database accessing is completed. ---------------------
        // step 1:  a mysql database is prepared.
        // step 2:  in window, install mysql,  npm install mysql -save
        // step 3:  code as below
        
        var mysql      = require('mysql');
        var connection = mysql.createConnection({
          host     : 'xxxxx.com',
          user     : 'xxxxx',
          password : 'xxxxx',
          database : 'xxxxx'
        });
 
        connection.connect();
        console.log('location 1') 
        connection.query('SELECT 11 + 22 AS solution', function(err, rows, fields) {
          if (err) throw err;

          console.log('location 2') 
          console.log('The solution is: ', rows[0].solution);
        });
        console.log('location 3') 
 
        connection.end();
        console.log('location 4') 
        
        // step 4, test, the result as below:
        
        C:\peter8\mynodejs\db1>node test_1
        
        location 1
        location 3
        location 4
        location 2
        
        The solution is:  33
        
        comments:
        1. event:When query a database is completed.
        2. event handler: the callback function.
        3. From the debug messages, it is a async pattern.
        4. For document database like Mongo, follows the same pattern.
       
        // scenario: HTTP post data events ----------------------------
        
        // step 1:  create a lab environment
        var express = require('express')
        var app = express()
        app.post('/', function(req, res){
            res.end("test events for http post")
        });
        var server = app.listen(3000, function(){
          console.log("Listening on port 3000, test 7:35")
        })
        // start the server, 
        // use ARC, select POST, set raw data to {"name": "Emi", "color":"white"}, click send

        // step 2:  test event data and end 
        app.post('/', function(req, res){

            var body = ""
            
            req.on("data", function(chunk){
                console.log("enter the handler for data event")
                body += chunk
            })

            req.on("end", function(chunk){
                res.end(body)
            })
            

            //res.end("test 1")
        });
        
        // replace the code for method post, and test, you'll see the response in ARC.
        
        comments:
             
             Callback argument req's method on, connecting the events and their handlers.
             

        // custom event, and its coding style   -------------------------------------     
        //code snippet from https:nodejs.org/api/events.html   for nodejs version 7.10.0
        //                                                             my version 4.4.2
        //After I added the code  "use strict", it started to work.

        "use strict"

        const EventEmitter = require('events')

        class MyEmitter extends EventEmitter {}

        const myEmitter = new MyEmitter();

        myEmitter.on('event', (name, weight) => {
          console.log('an event occurred! ')
          console.log('name  = ' + name)
          console.log('weight = ' + weight)
        });
        myEmitter.emit('event', 'Tairo', 30)
        console.log("strict test, test 3")  
        /*   test
            C:\peter9\0_nodejs\AppEvent_2>node appe2
            an event occurred!
            name  = Tairo
            weight = 30
            strict test, test 3
        */        
            

ESMA6

My Comments

    //  0.1   var vs const
    var hobby = 'hike'      // A variable with var key word is mutable.
    hobby = 'chess'
    console.log(`after hobby change, name = ${hobby}`)      // chess, changed

    const name = 'happy'    // A variable with const key word is not mutable.
    name = 'blue'                                           // no any error
    console.log(`after name change, name = ${name}`)        // happy, no change
    
    //  0.2.1  local scope, not using let keyword
    var name = 'Tairo'
    if (name != ''){
        name = "Emi"                // change it in local scope
    }
    console.log("name is " + name)  // you get Emi, change 

    //  0.2.2  local scope, using let keyword
    "use strict"                    // my nodejs is not latest, this piece of code is needed.
    let name = 'Tairo'
    if (name != ''){
        let name = "Emi"            // reuse it in local scope
        console.log(`inside the local scope, name = ${name}`)   // Emi
    }
    console.log("outside the local scope, name is " + name)     // Tairo

    //  1.1   template literals, interpolation  text only    -----------
    //        You can use res.end method for response.
    var express = require('express')
    var app = express()

    const name = 'Tairo'
    const name2 = `dog name is ${name}.` //`` is back ticks
   
    app.get('/', function(req, res){
        res.end(name2)
    });

    var server = app.listen(3000, function(){
      console.log("Listening on port 3000, test 7:11")
    })
            
// 1.2 template literals, interpolation, with html tag ------- // res.send method is required. const name = 'Tairo' const name2 = `<h2>${name} is my dog.</h2>` app.get('/', function(req, res){ res.send(name2) }); // 1.3 template literals, interpolation, multi lines ------- const name = 'Tairo' const name2 = ` <h2>${name} is my dog.&nbsp;&nbsp;&nbsp;&nbsp;won!!!</h2> <span style="margin-left:30px"><i>My dog is a happy dog.</i></span><br /> <span>We have another dog, Emi. She is happy too.</span> `
    //  1.4   object literal
    const myDog = {
        name: "Tairo",
        bark(sound){
            console.log(`You will hear ${sound}.`)
        }
    }

    myDog.bark('won')

    //  2.1  use arrow to replace function ---------------------
    //  classic function syntax
    function myFunction(p1, p2) {        // declare a function
        total = p1 + p2
        return total
    }
    var total = myFunction(2, 3)         // call a function
    console.log(`total = ${total}`)

    //  arrow syntax    (parameter...) => {function body}   
    var outputDogName = (dogName) => {   // declare a function as var
         console.log(`dog name is ${dogName}`)
         return `dog name is ${dogName}`
    }
    var dogName = outputDogName('Tairo')  // call a function

    //  2.2  passing function as parameter
    // classic
    var myTestFunc = (a, foo) => {   // function declaration
        var message = foo(a)         // use the parameter function
        console.log(`The person is ${message}.`)
    }

    // arrow syntax
    myTestFunc('Nutty', (value) => {return 'Professor.' + value})

    comments
    -You can see the significance of code terse feature in this scenario.
    - Because the parameter function is used once, function name is not needed.
    - The scenaro needs two functions - function, parameter funtion
    - In this case, the function uses the parameter function.
    - Other case, like jquery $.get method, the parameter is called from the jquery framework.
      reference:    https://api.jquery.com/jquery.get/
    - The function determine the code in parameter function.
    - Like using javascript array method - map,  filter, you have to follow their usages 
       to their parameter functions. 

    // 2.3  arrow example - array map method
    var tasks = 
             [ { 'name'     : 'walk dogs', 'duration' : 60},
               { 'name'     : 'breakfast', 'duration' : 30},
               { 'name'     : 'study', 'duration' : 120}]
    var task_names2 = tasks.map((task) =>  task.name )   
    console.log(`created in  map, the 1nd task name is ${task_names2[0]}`)
    
    Sequence of actions   
    - Method map allocates an empty array, then loops each task.
    - for each task, parameter function gets the data, appends to the array
    - Finally, method map returns the array. 
    - reference:  https://www.w3schools.com/jsref/jsref_map.asp 

    // 2.4  arrow example - array filter method
    // reference: https://www.w3schools.com/jsref/jsref_filter.asp
    var tasks = 
         [ { 'name'     : 'climb mountain', 'duration' : 150},
           { 'name'     : 'breakfast', 'duration' : 30},
           { 'name'     : 'study', 'duration' : 140}]
        var long_tasks = tasks.filter((task) => task.duration >= 120 );
        console.log(`there are ${long_tasks.length} long task`) // test
    
    // 3.1  class  - classic OO style
    "use strict"      // my nodejs is a bit old, without this code, I get the following error:
                      // Block-scoped declarations (let, ..., class) not yet supported 
    console.log("class 1,    test 1")

    class Vehicle {                                    // declare
        constructor(description, wheels){
            this.description = description
            this.wheels = wheels
        }
        describeYouself(){
            console.log(`I am a ${this.description} with ${this.wheels} wheels`)
        }
    }

    var coolSkiVan = new Vehicle("cool ski van", 4)    // use
    coolSkiVan.describeYouself()

    //  3.2 class extension
    class SemiTruck extends Vehicle {
        constructor() {
            super("semi truck", 18)
        }
    }
    var myVehicle = new SemiTruck()
    myVehicle.describeYouself()
    

JSON

 
    //  1.  hierarchy structure
    //  Unlike other hiearchy data technologies, JSON has its own way, ie, no child to parent, peer-to-peer.
    // This is a json data.
    const myData = {
        name: "Tairo",
        "desc": {
            color: "brown",
            "favor food": "beef"
        }
    }

    const name = myData.name                     // there are many ways to access.
    console.log(name)

    const color = myData.desc.color
    console.log(color)

    const favorFood = myData.desc["favor food"]  // single quotes will be OK.
    console.log(favorFood)
       
    //  2. mix of {} and [], key-value or value only
    const jsonObj = {fruits:  ['apple', 'orange', 'banana']}   // not key-value
    const fruits = jsonObj.fruits
    fruits.forEach( (fruit) => {console.log(fruit)})   // method forEach's parameter is a function

    //  3. partition json data
    /*
     - If you have a proudcts data in array, you can partition it, using filter method.
     - partition it
     - After you partition the data, you can use a ejs or pug file, using one subset.
    */
    //  json data
    const petFoods =  
        [
            {
                "id":          1,
                "pet":         "dog",
                "contents":     "chicken meat",
                "price":       20
            },
            {
                "id":          2,
                "pet":         "dog",
                "contents":     "pork meat",
                "price":        15
            },                              
            {
                "id":          1,
                "pet":         "cat",
                "contents":     "salmon meat",
                "price":        30
            }
        ]

    // partition
    const dogFoods = petFoods.filter((food) => food.pet == "dog")
    console.log(`dog foods has ${dogFoods.length} `)      // test
    
    //use array filter method, passing function as parameter for each item
    
            

HTML clients from the same nodejs web site

 
    // 1.1 HTML client
    lab-1  -------------------------------
    step 1:  create a new app, new app js file
    step 2:  create a new folder, public, add a new html file, myHTML.html with tag h1 and tag p.
    step 3:  in the command window, goto the app location, install expres
               => npm install express -save
    step 4:  code the app js file as below:
        var express = require('express')
        var app = express()
        
        app.use(express.static('public'))
        // express is not a build-in middleware module, npm install is required.
        // express.static is a middleware function.
        // app.use is to bind the app and the middleware function.
        // When the file inside folder public is accessed, there is no need to add public in the url.
        
        var server = app.listen(3000, function(){
          console.log("Listening on port 3000")
        })
     step 5:  run the server    => node app.js
     step 6:  open the browser  localhost:3000/myHTML.html
     
     lab-2 -----------------------------------------------------------
     step 1:  under folder public, add a subfolder css, add one css file with some code
                body {background-color: lightgray;}
                h1 {color: white;text-align: center;}
                p {font-family: verdana;font-size: 36px; }
     step 2:  in the html file, add one line of code in tag link
              link rel="stylesheet" href="css/style2.css"
              There is no need to add public in tag href. 
     repeat lab 1, step 5 and step 6

     lab 3 -----------------------------------------------------
     in the app js file, add two lines of code as below:
     
     var util = require('util')
     util.log("in app js")    
     
     when the start the server, you see  
            C:\peter9\0_express\AppHTML>node app1
            4 Jun 07:44:27 - in app js
            Listening on port 3000
     When you open the browser, enter the url  localhost:3000/myHTML.html
     You don't see any new log message in the command window.
     
     comments
         1. When you start the server, the server is created, its nodejs framework runtime is setup.
         2. It is not REPL, a script coding feature.
         3. When a web client makes a request, the HTTP method is not get.
         4. No app.get method, no res.render             
     


    // 1.2 HTML client from a ejs file  
    - continue from the previous example
    - under the root, add a new folder views
    - the add a file in it, myPage.ejs, copy some html code into it
    - in app js file, add the following
       
            app.set('view engine', 'ejs')
            app.get('/', function(req, res){
                res.render("myPage.ejs")
            });
       
    - start the server
    - open browser,  enter localhost:3000, you'll see the page. The url contains no ejs file name.
    - This time, the HTTP method is get, the html page from the response.
    - Because of using method get, it is a REST service.
    - Because of rendering the whole page, this web site is not a SPA, (single page application).
    - For passing data or using pug template, see my related topic.


    // 2. Ajax client for rest get - SPA
    - service
    - create an app
    - create app js file for get and post with root route, 
    - folder public is required, later create a html in it.
    - binding is required for the folder, code as below:
             app.use(express.static('public'))
    - install expres in window  as   npm install express -save
    - test with ARC client.

    - client
    - From W3C jquery reference, examine how the $.get is defined.
        - jquery api, $.get method has two parameters
            - the first is the service url
            - the second is the callback function, executed in the client,
              I have modified it using ES6 arrow syntax.
    - Then, copy its sample code into the html file, and modify a bit as below
        
        
        <!DOCTYPE html>
        <html>
        <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script>
        $(document).ready(function(){
            $("button").click(function(){
                $.get("/", (data, status) => {
                    alert("Data: " + data + "\nStatus: " + status);
                });
            });
        });
        </script>
        </head>
        <body>

        <button>Send an HTTP GET request to a page and get the result back</button>

        </body>
        </html>   
        

        
    - start the service
    - open browser, enterlocalhost:3000/myPage.html
       note: The folder name public is not in the url.
    - You'll see the response data is back in the same html page from the service.
    - note: jquery.min.js is a CDN(Content Delivery Network) as jquery library and framework.


    // 3.1 HTML rest client- post with form data
    - no ajax, pug(jade) for this demo

    - first, set up for getting a form ------------------------------
    //  create a new app, install express, and pug 
    //  under the root, add a folder views
    //  create one empty file myForm.pug
    //  get some HTML form code sample from w3c
    //  in html2jade.com, conver it into jade
    //  copy the pug code in the new pug file as below:
            doctype html
            html
              body
                form(action='/', method='post')
                  | First name:
                  br
                  input(type='text', name='firstname', value='Mickey')
                  br
                  |   Last name:
                  br
                  input(type='text', name='lastname', value='Mouse')
                  br
                  br
                  input(type='submit', value='Submit')
                p clicking the "Submit", the form-data will be sent to app.get of this site".

        // app.js code as below:
                var express = require('express')
                var app = express()
                
                app.set('view engine', 'pug')
                
                app.get('/', function(req, res){
                    console.log("in get")
                    res.render('myForm.pug')
                });

                app.post('/', function(req, res){
                    console.log("in post")
                    res.end("from post")
                });

                var server = app.listen(3000, function(){
                  console.log("Listening on port 3000, test 1:41")
                })
    - start the service
    - open your browser, enter localhost:3000 to see the form.
    
    // then, add the code to handle the post data -------------------------
    - Data processing in express service-side is similar to piping works on water.
    - One stage after another.
    - When some post data arrive from web to the server, and it is form data,
    -   the coresponding parser will process the data, to convert the data from byte stream to momory variables, 
        which are accessible, and stored in the request object.
    - Then, step into the data post processing, with data passing from the request object.
    - no change on the client code
    - install boy-parser,    => npm install body-parser -save
    - in the pplication js file
    - add the following code before app.post.
            
                var bodyParser = require('body-parser')        
                app.use(bodyParser.urlencoded({extended: false}))
            
            - urlencoded is a middleware function for parsing form data.
    - in app.post method, insert the following code to extract the form data
             
                var p1 = req.body.firstname
                var p2 = req.body.lastname
                console.log("firstname = " + p1)
                console.log("lastname  = " + p2)
            
    - start the service
    - open your browser, enter localhost:3000 to see the form.
    - enter form data, click button submit
    - Back to the service, you see the posting processing...
 
   
    // 3.2 HTML rest ajax client- post with json data --------------------
    - ajax using jquery, ejs(embedded javascript) for this demo
    - Single Page Application(SPA)
    - The post data in JSON format. When the service is only for json. 
    
    - create the skeleton app
    - create a app, install express, ejs, body-parser
    - setup folder structure as below
          MyApp
            public
              css
                myStyle.css
              js 
                myJSFile.js
             public
                myTest.ejs
           app.js

        
        // app.js
        var express = require('express');
        var app = express();

        app.use(express.static('public'));

        app.set('view engine', 'ejs');

        app.get('/', function(req, res){
            res.render("default2")
        });

        app.post('/', function(req, res){
            res.end("from post")
        });

        var server = app.listen(3000, function(){
          console
        
// myTest.ejs <!DOCTYPE html> <html> <head> <link href="css/style2.css" rel="stylesheet" type="text/css"> </head> <body> <h1>test ejs</h1> <p> 6/3/2017</p> <button onclick='sayHello()'>click me</button> <script src="js/myJSFile.js"></script> </body> </html>
        // js/myJSFile.js
        function sayHello(){
            alert("hello world");
        }

        - start the service  => node app.js
        - open a browser, enter localhost:3000
        - click a button to see the client side action 

        
- prepare a html page for json data from a ejs file ------ - create a new ejs file as below: <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script> $(document).ready(function(){ $("button").click(function(){ $.ajax({ url: '/', type: 'POST', contentType: 'application/json', data: JSON.stringify({firstname: 'Tairo',lastname: "Kao"}), success: function(response){ alert('the post is OK') }, error: function(xhr, ajaxOptions, thrownError) { alert(xhr.status) alert(thrownError) } }) }); }); </script> </head> <body> <button>Send an HTTP POST request to a page and get the result back</button> </body> </html>
    // in the app js file, modify code as below:
    
    var bodyParser = require('body-parser')        
    app.use(bodyParser.json())

    app.post('/', function(req, res){
        var p1 = req.body['firstname']
        var p2 = req.body['lastname']
        console.log("firstname = " + p1)
        console.log("lastname  = " + p2)
        res.end("from post")
    });
    
    // test to see posting json data. 
    

Enhancement-1: move ajax code into js folder

    - in public/js folder, add a js file
    - analysis
        - I tried to use $.post, but I could not make it to work.
        - Then, I use $.ajax, it works fine.
        - $.ajax({options in json}) including url...data, success...
        - $("button").click(function(){$.ajax({option in json})
        - When all are in the html file, the handler function is a
          anonymous one. If the code is partitioned, a name function 
          is required.
      
      
        // ajax code in a js file as below:
        function myFunction(){
            $.ajax({
                url: '/', 
                type: 'POST', 
                contentType: 'application/json', 
                data: JSON.stringify({firstname: 'Donald',lastname: "Duck"}),
                success: function(response){
                             alert('the post is  OK')
                          },
                error: function(xhr, ajaxOptions, thrownError) {
                            alert(xhr.status)
                            alert(thrownError)
                          }
            })
        };
        
        
// update ejs code as below <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <link href="css/style2.css" rel="stylesheet" type="text/css"> </head> <body> <button onclick="myFunction()">Send a POST request</button> <script src="js/MyJSFile4.js"></script> </body> </html>

Enhancement-2: get data from user, not hard coded-------------

step 1: in the ejs file, add two input tag First name:<br> <input type="text" id="fn"> <br> Last name:<br> <input type="text" id="ln"> <br><br> step 2: in the js file for ajax function, modify the code as below:
        const fn = document.getElementById('fn').value
        const ln = document.getElementById('ln').value     

        const myJson = {firstname: fn, lastname: ln}
        const strJson = JSON.stringify(myJson) // needed for this plateform
        alert("strJson = " + strJson)

        $.ajax({
            ...  
            data: strJson,...
        })
    
- start the service - open your browser, you see the form - enter data, click submit. - You see the debug post data in the client, and the service.

Custom Module, 12/10/2017


------------- demo 1 -------------

 
     code as below:

    // lib/dog.js           custom module
    var Dog = function(name) {     //es5 class constructor
        this.name = name
    }
    module.exports = Dog           // class name
    

// app.js using the custom module // line 1: create a class Dog // line 2: create a instance // line 3: test var Dog = require("./lib/dog") // file name without js externsion var dog1 = new Dog("Tairo") console.log("dog name is " + dog1.name)