Node Js
We can create our first module. greet.js and in this file we have:
A module should encapsulate code, the code inside greet.js is secure. We would have to explicitly make variables available.
call & apply let me borrow an object and overwrite the "this" key word.
Event Emitter:
OutPutting JSON: This time we are going to go out and get some data, and we are going to return it as JSON.
First, we have to tell it we are now working with JSON. res.writeHead(200, { 'Content-type':'application/json'})
We send back as a response the body! This res.end means this is the last thing that will be sent. \n is a carrage return, to be good.
Now we are missing one thing. Where does node map to the port? Remember the Port/IP ? How does it know when the information is sent to a particular port that node should receive that information so that is causing the request event to emit?
// we can overwrite them. john.firstname='John'; john.lastname='Roberts'; If we are looking for John, it will find it here, and will not go down the prototype chain, but if we say "greet", it will not find it on John, so it will seek down the prototype chain.
Object.create is a simple way to create a prototype chain.
Node has mapped what you see in the HTTP request, to a particular function.
So, on my app. I have access to verbs that are the same name, but lower case. app.get('/', function(req, res){ }) This will respond to a request where the verb is "get", and it will also map to a particular URL, and we give it a callback function that has a request and a response.
That reference is broken. What is returned from requiring? Module.exports.
So, our wrapper is going to return the module.exports value, not export which we changed to a variable breaking the relational reference between the shorthand exports & module.exports. Thus module.exports is returned from the required function.
What we get back is a buffer: So, what we could do is add-on a parameter to indicate the encoding we want to see: var fs = require('fs'); var greet = fs.readFile(__dirname + '/greet.txt','utf8', function(err,data){ console.log(data); });
Stream is a sequence of data: Chunk a piece of data set through a stream. It is also notable that steams inherit from eventEmitter as well. Look in streams.js to see.
So, I can reuse the same URL and there is logic behind the code that cause that API to run, and will look at our header like we did with our request object and make a choice.
That is the idea of API and EndPoints. They give and recieve data in a particular format, or sometimes multiple formats they will accept. The most popular these days is JSON. Javascript is really good with JSON.
These core native modules, you can look in the docs to see what they do. Some are global, others are not. Utilities, for instance, is not global.
how do we go out and grab this code. ? The required function of course. You need to require the appropriate thing. So, we require the util like this:
Files & fs:
var fs = require('fs'); //use method on fs object. We are normally dealing with // binary data. var greet = fs.readFileSync(__dirname + '/greet.txt','utf8'); //Sync is a sychronouse method of running the file. It will wait until it has the string back, then it will proceed. console.log(greet);
We want to use port 3000 on our local, but on the dev and production, it is another port. Node gives us some global variables to access these env variables. var port = process.env.PORT (variable name)
var port = process.env.PORT will go out to whatever env we are in and get the variable port the server is using. Then we can use a JavaScript trick to set a default value: var port = process.env.PORT || 3000;
No new copy of the object is made, you have two variables pointing to the same spot in memory. Thus when you change one, you change the other.
//pass by referrence function changeObj(d){ d.prop1=function(){} d.prop2 = {}; } var c = {}; c.prop1 = {}; changeObj(c); console.log(c);
0 1 0 1 Binary digit Base 2. 2^3 2^2 2^1 2^0 x x x x multiply 6, 4. 2, 1 2^X power 0 4 0 1 product. This is the binary rep of 5.
53 5 3 binary digit base 10 10^1 10^0 10 1 multiply 50 + 3 = 53 base 10 needs 10 digits to represent it.
We have a web-server that is running many programs. How do we know that Node.js is the program that should receive this information being sent to the server? We assign node a port - 443 a number that is unique - thus the information is sent to that port. With the IP address, we also specify the port.
78.132.160.4:443 When you put the IP address along with the port, it is called a socket address when you put it all together.
To use the app.post we need a http form: app.post("/person",urlencodedParser, function(req,res){ res.send("Thank ") console.log(res.body.firstname;) });
<form method="POST" action="/person"> firstname:<input type="text" if="firstname" name="firstname"/> </form> Important is name="firstname" do not forget.
Any name-value pair will be parsed and attached to the query object that exists on the request wrapping object that Express provides. If there is no query string qstr, then the query object will just be empty.
<html> <head><link></head> <body> <h1>Person : <% = ID %><h1> <h2>Query String Value: <%= Qstr%></h2> </body> </html> <% this is EJS %>
When the browser builds a GET request: what you will see is the query string in the header of the actual request: GET/?id=4$page=3 HTTP/1.1 Host:www.learnwebdev.net - So we then need to parse the HTTP request, pull out that data and put it in a format we can use in our code. By the way, Cookies come along for the ride as well.
A Cookie:username=abc:name=Tony - cookies are stored in your browser -
Templates and Template Engines: You can plug in a lot of template engines. If you pick one and download it, if it is programmed properly, then all you need to do is set the view engine. app.set('view engine', 'jade'); jade is the actual file extension of the file you are going to use. Then, you build your templates.
A template is just a utility that will take text and translate it into the html that should be delivered to the http response.
A TCP/IP is a stream anyway, it is sent in chunks, the browser is already use to dealing with data coming a chunk at a time and processing after it is downloaded, or as it is downloading. Since streams are fundamental to how the internet works anyway it is perfect.
API and EndPoints - API: A set of tools for building a software app. It stands for Application Programming Interface. On the web, the tools are usually made available via a set of URLs which accept and send only data via HTTP and TCP/IP
There are types of streams: Readable - read only. Writeable - Write only. Duplex - read and write Transform - change data as it moves through the stream. PassThrough -
Abstract Class (base) a type of constructor you never work directly with, but only inherit from. We create new custom objects which inherit from the abstract base class.
Same thing is accomplished: class Person{ constructor(firstname,lastname) { this.firstname = firstname; this.lastname = lastname; } greet(){console.log(`Hello ${this.fistname} ${this.lastname}`); } }
Anything you have added inside the object under the constructor works like a function constructor. Any item you put on the class - greet() is put on the prototype.
Node is written in C++ , node itself is a C++ program, this is because V8 is written in C++.
Asside: JavaScript concept: Javascript - ECMASCRIPT: The standard that Javascript is based on. Standards for JS.
class Greetr extends EventEmitter { constructor() { super( ); this.greeting = "Hello World"; } greet(data) { console.log(`${this.greeting} : ${data}`); this.emit('greet',data); } }
Asynchronous - more than one process running at the same time. Node does things asynchronously. Callbacks make this possible. V8 runs synchronous - one process at the time. JavaScript is also synchronous too.
Binary Data, Character sets, and Encoding:
Binary Data, Sets of 1s and 0s, each one is a bit (binary digit) Binary number 0101 represents data only with 0 adn 1s. How? It is math:
When you end up sending Json data from the browser side, maybe using a tool like jQuery to send some javascript objects on the browser side, on the client side. then you have a content type of: Content-Type: application/json and your actual Json string is also in the body much like it is when you are posting a form. { "username":"Terence" "password"."pwd" }
Both GET and POST have to do with the format of the HTTP request - so to get the data out, we are going to need some middle-ware to process this request so that we can work with the data.
This is how you will always run your node program. You can set a single entry point to run many files, but you must give it that entry point.
Break point is where we pause the code to figure out what is wrong with the code.
HTTP: Set of rules a format for data that is being transferred on the web. Stands for HyperTextTransferProtocol. It is a format defining data being transferred via TCP/IP.
Browser and Server have request and responce: Here is a typical : CONNECT www.google.com:443 HTTP/1.1 Host:www.google.com Connectin:keep-alive
This is a program embedded in node that is a C program - it parses requests and responses. It takes the data, breaks it up, takes a look at it, and knows what to do with it. Breaks up the headers, name: value pares, body - it can look at a http response, or request and break it up and we have those pieces of data as separate pieces of data.
Building A Server: We go get the http module with the require function: var http = require('http'); On the http module there is a createServer method. http.createServer( ); this creates a new server object. The createServer( ) method takes a callback. A function to be invoked. This actually turns out to be an eventListener. When this server object emits a particular event, the function will be called.
An example: app.post("/person",urlencodedParser, function(req,res){ res.send("Thank ") console.log(res.body.firstname;) }); When "/person" is seen, and it is a http post (verb) then urlencodedParser is a function that will be called, before the next function is called. similar to .(dot) use.
By using urlencodedParser we make sure the http request is formated properly from what is expected.
new int32Array(buffer) So, if we have 1 byte = 8 bits, and we configure the new array as : var buffer = new ArrayBuffer(8) we are saying 8(8bits) or 64 bits - new Int32Array(buffer) is creating an array of Integers 32 bits each, so we have 64 bits in our buffer, thus we can hold 2 numbers.
Callbacks - a function passed to another function that will be invoked at some point. function greet(callback){ console.log('Hello'); callback(); // envoking the function; } greet(function(){ console.log('The callback was envoked'); });
We can create a var for our buffer: var buf = new Buffer('Hello','utf8'); console.log(buf); // <Buffer 48 65 6c 6c 6f> (hexidecimal)
Can convert to JSON: buf.toJSON( ); { type: 'Buffer', data: [ 72, 101, 108, 108, 111 ] } buf.toString( ); Hello
greet.js var greet = function ( ) {console.log("from greet.js" )}; app.js require("./greet.js"); greet( );
Can we call greet from app.js after requiring the module greet.js? NO. Unless we give explicit instructions, you will not be able to call greet( ) from app.js. How do we give explicit instructions to share greet( )?
If you open the development tools, go to the network area. You can see the style.css, and if you look it requested it at the address of my site /assets/style.css Node saw the /assets and then passed it to the middleware, and we told the middleware to look for this fine style.css in that public folder that we told it to look.
Can you make your own middleware? Yes. app.use( ' / ' , function( req,res,next ){ console.log(' Request Url: ' + req.url); next( ); } whenever this rout is hit " / " this function will be executed. Then we will invoke next( ); next means run the next middleware.
We can store numbers, everything we store is binary. Binary is numbers, so everything we store is numbers! So, everything we store we must represent as a number.
Character set: A representation of characters as numbers. Each character gets a number. Like: h e l l o 104 101 108 108 111 We have a number than means a particular letter.
readable.on('data',function(chunk) }); Every time it reads the data, it will pass a "chunk" of data to the listeners.
Chunk! But, we can tell it to figure out what this buffer encoding: <Buffer 4c 6f 72 65 6d 20 49 70 73 75 6d 20 69 73 20 73 69 6d 70 6c 79 20 64 75 6d 6d 79 20 74 65 78 74 20 6f 66 20 74 68 65 20 70 72 69 6e 74 69 6e 67 20 61 ... 3021 more bytes>
Modules, Exports, and Require: Conceptual aside: Modules - a reusable block of code whose existence does not affect other code.
Common JS modules - agreed upon standards for how modules should be structured.
The require object returns module.exports it returns a property on a module.
Considering our wrapper function in node, all of our code is wrapped in a function expression. The first thing that is passed is the module.exports to the variable exports.
System events: from C++ from libuv - coming from the computer system. The computer finished receiving data from the internet. Things that JavaScript does not have.
Custom event that are completely different. Event Emitter. The javascript side is faking it. it is not real events, there is not event object. We can create an event library.
The C++ core - is the area of node js that builds the base. The foundation that builds the Node source code.
Dep..things built out of Nodejs, but are a part of node JS.
Express: package/packages: is just code that is managed and maintained with a package management system. Package Management System: Software that automates installing and updating packages. It also manages dependencies:
Dependencies: Code that another set of code depends on to function.
Environment variables: Global variables specific to the environment (server) that our code is living in.
Different servers can have different variable settings, and we can access those values in code. We can access those variables.
Middleware: code that sits between two layers of software that does things in the case of Express, between the request and the response.
Downloading files! Static files; not dynamic. Not process by code. HTML, CSS, Images. We want to add some static files that we are going to put in a folder called public.
If we write to the buffer; remember buffers are finite - buf.write('wo') will produce // wollo overwriting the first two chars.
ES6 - Typed Arrays: Good to know about them:
So, a URL you go to rather than returning a web application, gives you back data, and you can send data, send an HTTP request to that URL with data as part of the HTTP request and the API will do something with that data. That URL is called an EndPoint.
EndPoint: one particular URL that is part of a web API. Sometimes that endpoint (URL) does multiple things by making choises based on the HTTP request headers. So in my HTTP request, may put my data, but I may put something in the header some NameValuePare that has a meaning to that API endpoint. Maybe it will delete the data if I put one header, and give me data if I put another header.
WebServer Checklist: Better ways to organize our code into reusable pieces Ways to deal with files Ways to deal with DataBases The ability to communicate over the internet. A way to deal with work that takes a long time
Events and the event emitter: Events - something that has happened in our app that we can respond to. In Node, we actually talk about two different events. They are different.
Prototypal Inheritance Inheritance when one object gets access to the properties and methods of another object. Javascript implements what is called prototypal inheritance.
Every object has a property that points to another object, the object's prototype. The thing it inheritance from. We have what is called a prototype chain, and we have access to thoes properties on the prototype chain.
res.writeHead(200, { 'Content-type':'text/html'}) fs.createReadStream(__dirname + '/index2.htm').pipe(res); res.end(html);
Express does the content type for us:
We do not want to parse the body for every http request, so we are treating things differently depending on the URL.
First we get the URL encoded parser: and you can do this from the express website. // create application/x-www-form-urlencoded parser var urlencodedParser = bodyParser.urlencoded({ extended: false }) using this is good, because it makes certain that the http request is formatted properly from what is expected from the parser.
Query string is the easiest because the Express request object already parses it out for us.
For the query string value we are going to pass Qst: app.get('/person/:id', function(req, res) { res.render ( 'person', {ID:req.params.id, Qstr : req.query.qstr}); this object should end up having the query string value.
When we say writable and readable from NODES perspective: If we have a BROWSER that makes a request of a WEB SERVER then the request is readable.
From nodes perspective, the response from the server to the browser is writeable.
First class functions: Everything you can do with other types, you can do with functions. You can use functions like strings, numbers, etc. (pass them around, set variables equal to them, put them in arrays, and more)
Function expressions! a block of code that results in a value. var a=2; results in 2; "Hello" is a string; // function expression ! var a = function(){ console.log("hi"); };
What about responding to those URL as we did before: if (req === '/') { fs.createReadStream(__dirname + "/index1.htm").pipe(res); } We can deal with this easier:
HTTP METHOD: specifies the type of action the request wishes to make: GET, POST, DELETE, and others. Also called verbs.
When the browser and server connect - you have a IP - this will be the identifier. When the client and the server connects, each is given a IP or a set to numbers - this will be the identifier of how we connect the two systems together. When we make that connection, it opens a socket - a line, or connection which information flows. We wend information - normally the info is structured within its own type of protocol.
HTTP, FTP, SMTP....web, files, email...the "P" is protocol. They all travel from computer to computer using IP to identify - how we send the information protocol is TCP - Transmission control protocol.
Normally we work with a web address that maps to an IP address and a port such as https://www.google.com. You can assign a program to any port that you want. What is your mapping - what port number is being used.
HTTP: We know that TCP breaks up the data being send into packets and sends thoes packets to the server. But, how are thoes packets put back together?
EventEmitter.prototype has things on it like on/emit -- a stream.prototype inherits from EE, and we have different types of streams that enherit from stream.prototype -- Since thoes are abstract and we do not work with them directly, we have Custom Streams for particular purposes, the idea being - it has avaliable to it all of the functionality.
If the stream is readable - then node can read information from the stream. If the stream is writeable - then node can write to the stream. ect.....
Express Installation : A lot of the things we just did we can do in express with a lot less code.
If we look into the express folder we can find an express.js file. If we look into that file, we see that it exports a function; createApplication( ) and it is a function that returns a value app. We need to call this function, and what it returns is a function. So, we must invoke the function that is returned from require.
Both should be pointing to the same object as references. But, this is a querk in javascript. They are not the same. We changed what exports is, from an empty object to a function.
In javascript, when a variable is set equal to a value, it gets a new spot in memeory.
When you POST JSON data; POST / HTTP / 1.1 Content-Type: application/json Cookie:num4;page2 {"username":"Tony", "password":"pwd"} When you send it to a POST; then you have a content-type: application/json and your json string is also in the body.
In order to get the data out, we are going to need some middleware.
We can create our first module: in a file called greet.js we have console.log('Hello')
In our app.js file we can require( ) the module bringing it into our app.js file and running it. require('./greet');
Nodes Package Manager (NPM) - When we are talking about NPM we are talking about two different things: NPM - program install on your computer NPM - Registry is where the code comes from.
Init Nodmon & Package.json Init will set-up our dependencies - we go to the root and say npm init: then answer questions: When we install modules we use --save and the dependencies will be installed in our package.json.
MIME type: standard for specifying the type of data being sent> Stands for Multipurpose Internet Mail Extentions. Examples: application/json, text/html, image/jpg.
Inside of Node.js --- http-parser https://github.com/nodejs/http-parser
$ npm install body-parser --save Now that it is installed, how do we use it.
It is a module (look at the instructions on github) we are going to have to require it. var bodyParser = require('body-parser'); So, now we have this object given back to us from the require.
Require is a function that you pass a "path" to. module.exports is what the require function returns. This works because your code is actually wrapped in a function expression, that is given these things as function parameters. What you write is actually the body of the function.
JSON what is json? It is a standard for structuring data that is inspired by javascript. It may look something like this: { paramer }
When we are talking about coding, we are talking about how many bits are we using to represent each number. UTF-8 is 8 bits. The more bits, the bitter the number we can represent.
JavaScript does not deal well with the encoding part. But the pure raw binary data, JS is not that good. Node expands on the JS language and give us mechanisms to deal with raw binary data.
The mime for this is "application/json" We can then create an object, which can easily be converted to JSON. var obj = { firstname:'John', lastname:'Doe' };
Javascript deals with Json very well: We can res.end(JSON.stringify(obj))
Node Core: Servers and Clients - Clients and servers talk to each other and request and respond to each other through Http Request and Http response.
Javascript is the standard when writing in the browser. The features in the browser are made available to javascript, and through Javascript to do work.
Callbacks - function that passes to another function which we assume will be invoked at some point. We pass a function - to another function -
Libuv - The Event Loop, and Non-blocking Asynchronous Execution:
So, we have custom module and native modules. If custom we specify the location or path, if native we just use the native name. require("../path/path"); require("util"); * try not to name custom and native modules the same.
Modules and ES6 Node added modular structure to JavaScript - ES6 includes this modular structure -
JSON is just data, but looks like a JS object, but parenthesis are also around the { "property" : "value", }
More on require function: If require can not find greet, it will look for a folder, and then look for an index.js file.
lim is full of JS files. Process.binding that will go out and get the c++ and making it available to Js.
Node -v is a command you can run that has no errros, meaning that node is there.
TCP takes the information and splits it into pieces - much like chunks, and send those pieces one at a time through the socket and that individual piece is called a packet.
Node allows us to make the connection, and send the information over the sockect. TCP looks like a stream - a chunk, node treats these packets like chunks, and that is true.
1.Better ways to Organize our Core into Reusable Pieces. 2. A better way to deal with files. 3. Ways to deal with a Database. 4. The ability to communicate over the internet. 5. We need to be able to accept a request and send reponses in a standard format. 6. Way to deal with work that takes a long time.
Node can solve these problems.
Really we just do module.exports..........and this is lower cognitive load, we just do this. module.exports
Node comes with Native Modules you can access:
Stream and buffers: Buffer is a spot in memory that is intentionally limited in size to provide a holding spot to gather data and then move it along.
Normally moving through a stream - water (data) flows through a stream from one process to another. Data flows to the buffer, then is pushed on to process. The buffer gathers enough data to continue processing the data.
var express = require('express'); var app = express(); var port = process.env.PORT app.get('/', function(req,res){ res.send('<html><body><h1>HI World</h1></body></html>') }); app.listen(port);
Notice we did not do a content type ! var express = require('express'); var app = express(); var port = process.env.PORT app.get('/', function(req,res){ res.send('<html><body><h1>HI World</h1></body> </html>') }); app.listen(3000);
To review: We understand, we are pulling the http module from the node core, we are then creating an object with createServer( ) that is given a callback - The object is actually an event listener; and wrapped up inside the Javascript module the parser is giving us a request and a response that allows us to send information back down the stream. Things like status, headers and the body itself that we are sending.
Now that we have a server; lets look at outputting HTML and Templates: http.createServer(function(req,res){ res.writeHead(200, { 'Content-type':'text/plain' }) res.end('Hello World \n'); }).listen(1337,'127.0.0.1');
"moment": "^2.10.6" The carrot is important. We are saying any update to minor, or patches - 6 & 10 then update me. If there is a change in the Major then there will be no update. if you change the carrot to a tilday ~ then this means only give me patches.
Now you have the module available and the dependencies are listed. We normally delete the node modules - so you can know what are the dependencies by looking at the pacakage.json file. . You can use npm install and what this will do is look at pacakage.Json and install all the dependencies listed.
we create a person.ejs : using the same html except we are using ejs code to run javascript within the <% javascript %> <body> <h1>Person:<% = ID %> </h1> </body> (got to get the syntax right)
Now, how is it going to get this data? The render method, we can give a javascript object. We use the same way to access the data: req.params.id app.get('/', function(req,res) { res.render('person',{ID:req.params.id}); });
When the browser sees a form: it takes the values that are typed into the fields and sets up the query string: name = value, based on what you typed in.
Now, if we want to handle Json - if we look at the express site: https://expressjs.com/en/resources/middleware/body-parser.html#bodyparserjsonoptions
Inheriting from the event emitter: There is a method called inherits: exports.inherits = function ( ctor, superCtor) takes two constructor ctor (want to add new properties) SuperCtor (properties you want to be added are sitting)
Now, if you connect the objects, you have access to its prototype chain, and methods.
var http = require('http'); var fs = require('fs'); http.createServer(function(req,res){ res.writeHead(200, { 'Content-type':'text/html'}) var html=fs.readFileSync(__dirname + '/index1.htm') res.end(html); }).listen(1337,'127.0.0.1');
Now, what if we wanted to make this dynamic? We create a file index2.htm <html> <head> <body> <H1>{Message}</H1> </body> </head> </html>
So, we will build our own event emitter! This will help understand the node event emitter and all the modules on top of it.
Object Properties, First Class Functions and Arrays:
This will cut down on mistakes, and will enable us to use he telesense to help keep things in order.
Object.create AND prototypes: How we can set-up prototype chain: Here is one way to do it.
Systems events are managed by Libuv - V8 runs one piece of code at a time, and this keeps happening as functions are called. There is a library INSIDE of 8V called libuv. libuv deals with events occurring within the operating system. Libuv connects to the OS (operating system) and requests to download something from the internet. Libuv has a Queue inside of it. The event loop. A Queue of events that have completed - Libuv is constantly checking the queue to see if things have happened. At some point, the OS completes the task and the event is placed in the Queue as done. There may be more than one event that is done and placed in the queue.
On every loop, Libvu checks the Queue and when something is finished, Libuv pushes the code back onto the stack when V8 has finished running its code.
How does the information actually gets to the node process:
PORT - once a computer receives a packet, how the computer system knows that program to sent it to. When a program is set up on the operating system to receive packets from a particular port, it is said that the program is "Listening" to that port.
Express Routes We can look at the documentation on expressjs.com at Routing; and see the different things we can do with routing.
Passing Variables Via the Router: app.get( ' /person/:id ', function(req,res ){ res.send('<html> code and + res.params.id') } we send with /person/:id " : " means anything. To retrieve: req.param.id NOTE to use the req NOT the res.
If you deal with cookies, then there is a good cookieparser() on the Express site under middleware. This will take the http request which includes cookies separated by semicolons. This gets sent along for the ride for every http request for any site. This will pull this string out of the http request, breaks it apart, and then adds it on as a reg.cookies as a request and the calls next. So when you call a route "/" it grabs this information and stores it as a (dot) . cookie.
Passport middleware that checks if a person is signed in before you give them data.
Pipes: We add one more idea that builds on the idea s streams and buffers:
Pipe : connecting to two streams by writing to one stream what is being read from another stream.
You pipe from a readable and writing to the writable with that chunk. think of this, if you have a chunk that is readable and writable, then you can pipe the chunks along a flow of streams.
Pipes: We can do the entier process of reading and writing with a lot less code: var fs = require('fs'); var readable = fs.createReadStream(__dirname + '/greet.txt'); var writable = fs.createWriteStream(__dirname + '/greetPipe.txt') readable.pipe(writable)
HTTP Begin a web server: TCP / IP
Protocol: set of rules two sides agee on to use when communicating. So, bot the client and the server are programmed to understand that set of rules.
There are a lot of choise; jade, ejs, there are many view engines.
Querystring & Post Parameters: When the browser builds and sends a GET request in the header of the actual request: A simple query string would be something like this: localhost:3000/person/21?qstr=123 and it appears in the browser.
"c" is a empty array, and then we add a "c.prop1" to it which is an empty array. When we pass "c" to the function changeObj("d"), "d" points to the same location in memory. Thus, any changes to "d" will affect "c".
Remember, when I pass a object to a function, we can add properties to that object that will be reflected outside of the function.
An object is binary data in memory: We can convert it, serialize it into a format that can be transferred or stored.
Routing: Routing: mapping HTTP request to content: Wheather actual files exist on the server, or not. We may have a url/image.jpg, we receive that request. Maybe that image does/does not exist, but we can respond to the request. When I receive a request for this URL, I will give it this response. Maybe go to a database and get the image because it is not on the file server itself.
The new syntax in ES6 is : greet.js export function greet() {"Hello"}; app.js import * as greetr from 'greet'; greetr.greet(); This is similar to Node.
Same concept, having code encapsulated in modules, and exporting only what you want to have available outside of the module.
Immediately Invoked function expressions (IIFE) When we are talking about modules, we are also talking about code that is protected. Code that does not impact any other code in our software. We are taling about scope.
Scope means wherein the code you have access to a particular variable or function. If the scope is only a function, then you only have access to that variable within that function.
So, we can very easily get an object, or have an object sitting on the Node side, get that object, convert it to JSON (serialize) it. Then on the browser side, take it and convert it to a JS object.
Serializse: Translating an object into a format that can be stored or transferred. JSON, CSV, XML, and other popular formats. Deserialize it the opposit, converting the format back tino an object.
We need to tell the JS engine that our function is an expression, which is run immediately. We can turn the function into an expression by putting parentheses around it. ( function ( ) {} ) This now tells JS that this is an expression, and Js will run it immediately.
So ( function ( ) { } ( ) ) We have a function expression, and ( ) we have invoked it. IIFE!
Now, we have access to two modules, through one index.js file. We can call both in app.js. greet.english( ); greet.spanish( );
So, lets add a feature: The require function can process a .JSON file. greetings.js (holds the json file) { "en":"Hello", "es":"Hola" }
app.get(' /does patter matching/:id) Look in the documentation for many.
Static Files and Middleware What we are doing is when we send a request, there are things that happen between the request and the response.
You may need a jssconfig.json file. Tells the compiler we have ES6 code.
Template literal : A way to concatenate strings in JS ES6. Easier to work with than a bunch of +
variables within a function are scopped to that function only. You can not access variables in a function outside of that function. var firstname = "Jane"; (function(){ var firstname = "John"; console.log(firstname); } ()); console.log (firstname);
The firstname outside of the function is not impacted by the variable firstname within the function. They have different scopes.
exports vs module exports: Remember when our code is run through node, it is wrapped in a function expression ( function (exports, require, module, __filename, ___dirname) { var greet = function() { console.log('hello'); }; module.exports = greet; });
The function is executed - the first parameter is fn(module.exports. .....) exports is a shorthand for module.exports. Two variables pointing at the same module in memory.
The code will get the text, and fill the buffer. If the text length is the same size as the buffer, then it will take all the text and fill data, but if the text is larger than the butter size then you will get pieces of the file at the time where each piece is the size of the buffer.
The readable will fill the buffer, then emitt the data event and will envoke all the listeners, and then do it all again untill if finishes the file.
Then we want to read the file: fs.readFileSync(__dirname + "/index1.htm"); We know this is a buffer from our previous studies:
Then finally we want to send the file back to the browser: res.end(html);
There is a pattern we can use to remedy this: if we create a file, config.js file. And we standardize the input. module.export ={ events:{ GREET:"greet" } }
Then we use this everywhere there is a "greet". emtr.on(eventConfig.GREET,function(){ console.log("Someone said hello! "); }); emtr.on(eventConfig.GREET, function(){ console.log('A greeting occured')
We could format this a little: console.log(moment().format("ddd,hA") and get : Mon,6PM (ddd === day, h=hour, A===am/pm)
There are also development dependencies: Thoes items we do not need for the program to run, but programs we want to use while building our app. Like, jasmine (a tool to automate / build test as I build the software.
class Greetr extends EventEmitter { constructor() { super( ); this.greeting = "Hello World"; } }
This accomplishes the same thing as the older way of doing it with call and util.
In general, there are things called headers which are name-value pares, header: value, like Host: www.google.com.
This is a responce from the server: HTTP/1.1 200 OK (status) Content-Length : 44 (Headers) Content-type : text/html (content type) <html><head>....</head></html>
http.createServer(function(req, res ){ res.writeHead(200, ) }); A HTTP response starts with what is in the head. writeHead is a method that helps build that HTTP response. We can say what the status code is 200, then we can specify the HEADERS, those name-value pairs.
This is a responce from the server: HTTP/1.1 200 OK (status) Content-Length : 44 (Headers) Content-type : text/html (content type) <html><head>....</head></html> An easy way to specify the headers is to use an object, since that is what an object is, name-value paries.
-g means Global - it is saying, download this so I can use this anywhere. It can be accessed from anywhere on the computer.
This is how we will install nodemon. To update all of the dependencies that need updating, you can run npm update.
var fs = require('fs'); var zlib=require('zlip'); var readable = fs.createReadStream(__dirname + '/greet.txt'); var writable = fs.createWriteStream(__dirname + '/greetPipe.txt') var compressed = fs.createWriteStream(__dirname + '/greetPipecomp.txt.gz') var gzip = zlib.createGzip(); readable.pipe(writable) readable.pipe(gzip).pipe(compressed);
This method of writing from method, to method is called chaining.
We then create a new object Police using the new operator: var officer = new Policeman( ); We may think that the officer.greet( ); is valid. But, it is not. Indeed Policeman ( ) did inherit all of the properties on the prototype People( ), and this is true. BUT function Person(){ this.firstname = 'John'; this.lastname = 'Doe'; } The Person.prototype does contain Person.prototype.greet=function( ){ console.log(`Hello ${this.firstname} ${this.lastname}`) } but function Person(){ this.firstname = 'John'; this.lastname = 'Doe'; } Was not run!
Thus when creating a new Policeman we need to include all of the properties and values on the Person object. function Policeman( ) { Person.call(this); badgenumber:"1233"; } this points to an empty object, but when we call Person using the call statement, we assign this to the values of the function.
createServer( ) While we give it a call-back, createSever is an object, and on that object, we have inherited from the event emitter the same methods as the eventEmitter() has. Namely the Listerner. .
Thus, the server will listen for an emitter, so that when it "hears" the emitter, the server executes the callback function.
ES6 and Classes: We have a function Constructor: function Person(firstname,lastname){ this.firstname=firstname; this.lastname= lastname; }
To convert this to ES6 Class: class Person{ constructor(firstname,lastname) { this.firstname = firstname; this.lastname = lastname; } }
$.ajax({ type:"POST", url:"/personjson", data: JSON.stringify({firstname:'Jane',lastname:'Doe'}), dataType:'json', contentType:'application/json' });
To put together a POST - we used ajax() - this is what a post looks like. This is run inside of the browser; had we used the ejs delimiters <% %> then this would be run inside node. The browser will send this as part of the final text, sent as the response in the body. Node.js will run the request, use the jsonParser to pull out the body, and parse that json within the body, and we will have this data available.
We can create a file, app.js and put something simple in it. let a = 1; let b = 2; let c = a + b; console.log(c);
To run this, we go to the file location and type: node app.js and the app will run.
Javascript engine - converts code into something a computer can understand.
V8 Under the hood. Open-source. v8 can be run as a stand-alone, or within any c++ program as embedded. V8 has "hooks" that I can use to add features to javascript. It makes anything you can do in C++ available to javascript.
Buffers In Node: C++ side of code. The buffer holds raw binary data, 0s, and 1s. You can specify a size.
We also give it the encoding as well:
Then we go to our app file and include: app.get('/', function(req, res) { res.render('index'); }); Rather than using send, we use renter("index") and tell it the name of the file we will be rendering. It says okay, I will look in the view folder and look for the file that you have told me to look for. I will then take that file, process it, and then render it.
We are going to use a template tool called ejs to render our views. We are also going to pass some data to the view, the person id we did earlier.
Event Emitter: Magic String: A string that has some special meaning in our code. This is bad because it makes it easy for a typo to cause a bug, and hard to fine.
We are relying on the string "greet" to fire our functions. lets remove the relying to typing it correctly.
var readable = fs.createReadStream(__dirname + '/greet.txt',{encoding:'utf8'}); and get back the words so I can read them.
We can actually limit the amount of bytes coming back by adding the option highWateMark: 32*1024
if (req === '/') { fs.createReadStream(__dirname + "/index1.htm").pipe(res); }
We can also add '/api' if (req.url === '/api') { res.writeHead(200, { 'Content-type':'application/json'}) var obj = { firstname:'John', lastname:'Doe' };
Streams are abstract, we never work directly with them. Inside the FS.createReadStream =
We can create a readable stream by: var fs = require('fs'); var readable = fs.createReadStream(__dirname + '/greet.js');
// functions and arrays var arr = [ ]; arr.push(function(){console.log("hello world 1") }); arr.push(function(){console.log("hello world 2") }); // Three functions sitting in an array. We can invoke it. We need loop. arr.forEach(function(item){ item(); });
We can have an array of functions, and loop across the array with a array.foreach statement and invoke the functions in the array.
One thing to note: The scripts line. This is command-line commands: we can say npm test and the scripts will run. "scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
We can now install moment: "a date module" npm install moment --save: --save will make sure this is added to our dependencies:
var http = require('http'); var fs = require('fs'); http.createServer(function(req,res){ res.writeHead(200, { 'Content-type':'text/html'}) var html=fs.readFileSync(__dirname + '/index2.htm','utf8') html = html.replace('{Message}', message); res.end(html); }).listen(1337,'127.0.0.1');
We can pull the contents of a file, and filling a template dynamically.
//object properties and methods var obj = { greet:"hello" }; console.log(obj.greet) console.log(obj['greet']); // we can create a variable, and then use that variable. var prop = 'greet'; console.log(obj[prop]); //this is key!
We can use a string as a value to grab a property or value of a property on an object. var prop = 'greet'; console.log(obj[prop]); //this is key!
var bufffter = new ArrayBuffer(8) wants a size in bytes. One byte is 8 bits, or 8 0's and 1's . We sad 8 so 8 X 8 is 64 0s and 1s. This is coming from V8 - How do we deal with the buffer? We can create a view - var view = new Int32Array(buffer)
We change the array, we are actually changing the buffer, when reading from the array, we are actually reading from the buffer. It is a way of dealing with the buffer.
We are sending text at the moment. We want to send HTML - we do not want to store the html in strings inside node. We want a file: index.htm
We create a file index.htm with some html in it. The first things we will need if we are going to be dealing with files is to require the fs module from the node core. var fs = require('fs');
How do we create this chain? There is the ES6 class. Function Constructors: A normal function that is used to construct objects. The "this" variable points a new empty object, and that object is returned from the function automatically.
We do this by using the new key word. Then we can use the this key word and assign properties:value pairs.
We could pipe the readable stream to the response stream. res.writeHead(200, { 'Content-type':'text/html'}) fs.createReadStream(__dirname + '/index2.htm').pipe(res); res.end(html);
We have a response stream, we write to it, then we say take a readable file stream, and pipe it to this response stream. So, every chunk will be read to a buffer and piped to the response stream. This means we read the file a chunk at a time into a buffer we keep small and then pipe it to the response stream. Faster, more performant.
We start with requiring uitl: var util = require('util'); and we add a object Person: function Person(){ this.firstname = 'John'; this.lastname = 'Doe'; }
We know that every object has a prototype where we can add properties to So, we can add the greet() function to Person: Person.prototype.greet=function( ){ console.log(`Hello ${this.firstname} ${this.lastname}`) }
If we want to deal with a form being posted, or Json being posted, we will need to deal with the body of the http request. Express does not to that out of the box. We need something that will look at the request and give us access to the information - parse the content of the HTTP request so we can work with it.
We need a middle-ware: and we will use body-parser. There are more than one - the idea is that it will parse the body of the http request.
Our server listening on port 3000: var express = require('express'); var app = express(); app.listen(3000);
We use 3000, but we do not want to use this when we deploy our app. We want to use env variables.
We create another object: Policeman() function Policeman( ) { badgenumber:"1233"; }
We want Policeman to inherit all of the properties on Person, especially greet( ) Thus, we can use the uitl for this: util.inherits(Policeman,Person);
The Browser is sending a http request, and the URL is one of those peices of data. It is up to the sever to do somethnig with it.
We want to give different responses based on the URLs.
Or, it may be on the server and we connect to it and stream it back. Or maybe we have to do some manipulation to it before sending it back.
We want to send a specific responce to different URL request. So, if we go to localhost:1337/somefile.html we get the same data back.
var util = require('util'); So, what does util do? It makes things easier for us. So, if we want to do a string, rather than doing all the "name " + var, we can do this: util.format("hello, %s", name) and rather than using console.log() we can use util.log(greeting) and it will do the same as console.log(greet) but with a time stamp. 12 May 12:07:19 - hello, Terence
We will use a lot of Native modules and we will gab that code via require.
V8 Processors: A tiny machine - We give the MP a language, We give the MP instructions. MP will speak IA-32, x86-64, some speak ARM, MIPS. It is a machine that accepts instructions and carries them out. Machine code: Programming languages spoken by computer processors. All code becomes machine code.
We write in languages that are compiled into machine code. We write high level languages such as JavaScript. Javascript is inspired by C/C++.
The goal with node is that you need to use only one programming language for both front end and back end. And, we can add on things to javascript to get things done.
What does Javascript need to manage a server? What are the features we need to do the kind of things a web-server needs to do.
Within public we have styles.css. How are we going to download these files? We are going to use middleware! app.use('/assets', express.static(__dirname + '/public'));
What is going to happen is the browser is going to download the HTML, see the link tag, and generate an HTTP request for mysite/asset/style.css. That HTTP request will be handled by NODE and when Node sees the /assets, and it says anything after that I will look for it in this /public folder.
Objects and Object Literals Name value pairs - A name that maps to a value; address = "100 main street" Javascript objects (a collection of name value pairs) An object sits in memory and points to other values.
When a function is within an object, we call it a method.
Localhost translates to this IP address: 127.0.0.1
When the browser makes this request: . listen(1337,'127.0.0.1'); then the browser will receive that request. The parser wrapped up in the JavaScript code will give us the request, and we can send back the response.
When we pass an object to a function something very different happens: "a" = Object (name-value pairs), the object is sitting in a particular place in memory.
When we call a function and pass it to a function "b"="a", that variable or parameter inside the function points to the same place in memory. This is passing by reference.
ID can be used as a regular variable. Most of the view engines work this way.
When we input http://localhost:3000/person/1, we know there is not really a file folder person, but the URL things there is. So, when it looks for our style.css file, it is looking in the folder person. We need to make sure the browser understands we are asking for it particularly at the root directory.
Semantic Versioning (sumver) Versioning specifying what version of a code this is. The word "semantic" inplies taht something conveys meaning. semver.org
When we say a number version: Just looking at the verison gives us some information: Major . minor . patches 1.7.2 2. as bugs are fixed, you increment this number. No changes that will break code if someone is using my code. Still backward compatible. 7. Adding some new features. Your code will work fine. Still backward compatible. 1. Big changes. Your code will/maybe break.
var greetMe = function( ) { console.log('Hi, Tony'); }; // tunction expression! and you can call it greetMe( ); logGreeting(greetMe);
You can also create a function on the fly like this: logGreeting(function(){ console.log('Hello'); });
<link href="assets/style.css" type="text/css" rel="stylesheet"/> To make sure the browser knows to look from the root, we need " / " in front of assets/styles.css. <link href="/assets/style.css" type="text/css" rel="stylesheet"/>
You can insert JavaScript into the template engine <%ID.length%> here we inserted ID.length.
You can connect middleware together - it allows us to build reusable ways with http requests and responses. We can use other people's middleware, to save time. We can specify it according to the route.
You can leave off the route, and it will do it for everything no mater waht the route is. app.use(function (req, res, next) { console.log('Request Url:' + req.url); next(); }); If you do not include a route, then the function is always used.
JavaScript: Node ES6 and template strings. New standard:
You can take the new features in JS and use babeljs.io to convert them to the old Js so all the browsers will us them.
greet.js var greet=function( ) { console.log("Greet"); }; module.exports = greet; //now this module is exposing the greet( ) outside of the module.
app.js
if we set a variable equal to the required file, and we have module.exports = greet; Then we will have access to the greet function in the greet.js file.
app.js var greet = require( './greet ' ); greet( ); // we now have access.
index.js var english = require('./english'); var spanish = require('./spanish'); module.exports ={ english:english, spanish:spanish };
app.js var greet = require('./greet'); greet.english(); greet.spanish();
So now we can set the view-engine. app.set('view engine' , ' ejs '); The file extention is going to be ejs.
by default the express fraimwork will look for the files (views) inside a folder called views. Views means your user interface, your UI.
Changing our Event Emitter to use ES6 Classes: Create a class: 'use strict'; class Greetr { constructor() { this.greeting = "Hello World"; } } This is a class in ES6 - Greetr. We wanted to inherit from the EventEmitter and call it. To do this in ES6 - we use extends
class Greetr extends EventEmitter { constructor() { this.greeting = "Hello World"; } } Greetr extends EventEmitter: To call EventEmitter you use super( );
What about adding prototypes? Person.prototype.greet=function(){ console.log(`Hello ${this.fistname} ${this.lastname}`); }
class Person{ constructor(firstname,lastname) { this.firstname = firstname; this.lastname = lastname; } greet(){ console.log(`Hello ${this.fistname} ${this.lastname}`); } }
exports.module= greet; This exports. module, only things I give to this will be exposed to app.js, or whatever file that requires greet.js. Now greet is exposed.
console.log("hello"); var greet = function(){ console.log("Var greet"); }; greet(); module.exports=greet;
Typing node enter will start a command interface. 1 + 1 and we get a response 2.
control-c twice to stop node. now we are going to put our javascript into a file.
Node js. Do not imitate, UNDERSTAND - Conceptual Aside: The command line interface - BWA Command line interface : A utility to type commands to your computer rather than clicking.
dir /w (argument) BWA arguments - are values you give your program that effect how it runs. Essentially you are passing parameters to a function.
You can give it arrays, objects, loops anything.
ejs is good, but other template engines have what is called layouts. Where you define a single parent page, and embed the child pages inside of it.
function Person( firstName,lastName ) { this.firstName = firstName; this.lastName = lastName; }; var john = new Person(" John ", " Roberts " );
function Person( firstName,lastName ) { this.firstName = firstName; this.lastName = lastName; }; Person.prototype.greet = function(){ console.log("Hello Greeting"); } var John = new Person(" John ", " Roberts " ); console.log(John.firstName); console.log(John["lastName"]); console.log(John.greet());
Functions in JS are objects, a special king of object. You can pass functions around, even to other functions.
function greet(){ console.log('hi') }; greet(); //functions are first class, we can pass them. function logGreeting(fn){ fn(); }; logGreeting(greet);
We create a function: function greet( ) { console.log( 'Hello' ); }; This function will take a callback!
function greet(callback ) { console.log( 'Hello' ); }; The callback will be a function itself: Remember functions in Javascript are first-class: You can pass them around as you would any variable.
We can also pass data to the callback from the greet function - say we went out and got some data.
function greet(callback){ console.log('Hello'); var data = {name:'Terence'} callback(data); } greet(function(data){ console.log(`My name is ${data.name}`); }); This is a patter :
greet.js var greet=function( ) { console.log("Greet"); }; app.js require(./greet); greet( )
greet( ) will be undefined in app.js - thus this is by design. The modules are completely secure. We can make greet( ) avaliable.
We are going from a letter to a number, but remember the number is stored in binary. Character encoding: how characters are stored in binary. The numbers or code points are converted and stored in binary.
h e l l o 104 101 108 108 111 Character encoding UTF-8 01101000 ect....
The values we will give it a mime type. The mime value for plain text is " text/plain ". Then we will send the body.
http.createServer(function(req, res ){ res.writeHead(200, { ' Content-types ': ' text/plane ' } ); res.end( ' the body, I am done sending, this is the last thing I am sending \n ' ); });
var express = require('express'); var app = express(); /look inside of the application.js and we find a listen method we find: app.listen = function listen( ) { var server = http.createServer(this); return server.listen.apply(server, arguments); }; so we can call listen an give it a port. app.listen (3000);
http.createServer(function(req,res){ res.writeHead(200, { 'Content- type':'text/plain' }) res.end('Hello World \n'); }).listen(1337,'127.0.0.1');
http.createServer(function(req,res){ res.writeHead(200, { 'Content-type':'text/plain' }) res.end('Hello World \n'); }).listen(1337,'127.0.0.1'); Listen is just a metaphor for "when information comes to the server, here is the PORT, if it is sent to that port via that address then send it to me. and you can see the port 1337 and the internal http address: 127.0.0.1 (standard internal IP address for the local system)
http.createServer(function(req,res){ res.writeHead(200, { 'Content-type':'text/plain' }) res.end('Hello World \n'); }).listen(1337,'127.0.0.1');
If you want to pass data to the event listener? You can do this with the node event. Greetr.prototype.greet = function(data) {console.log(this.greeting + ' : ' + data); this.emit('greet',data(what you want to pass) )
in the listener you just have to expect it. greeter1 = new Greetr( ); greeter1.on('greet',function(data){ console.log('Someone greeted!: ' + data); }); greeter1.greet("Tony");
Most of the time within the code there is a folder called view. This is simply where the UI or views are kept. So, we enter a file called index.ejs and we put some code in it.
index.ejs <html> <head> <link href="assets/style.css" type="text/css" rel="tylesheet"/> </head> <body> <h1>Hello World</h1> <p> I am here! </p> </body> </html>
A GET request may look like this: localhost:3000/person/21?qstr=123 - you actually see the query string within the browser when the page comes up in your browser.
localhost:3000/person/21?qstr=123 : we need to pull out that data and put it into a format that we can use in our code.
So, now let's go to the html person: <h1>Person:<%=ID.length %> </h1> <p><h2>Querystring value: <%= Qstr%></h2></p> When the GET request happens, if there is a Qstr value it will attache it on the model object {ID: req.params.id, Qstr:req.query.qstr}
localhost:3000/person/Tony$qstr=123 generated a http request that included the query string in the header and that was parsed and made available via the (dot) .query object as a property on the query object.
" ./ " means it is on the same level as our app.js file.
modules encapsulate code. unless we explicitly give access.
EJS.co Express gives us the means to connect the URL of the file, the route and the data that the template may need to use.
npm install ejs --save (to insatall)
You can do the same with apply: The only difference is if you are passing prameters to the object, with apply you pass an array. var obj= { name : 'John Doe', greet:function(key){ parameter=key; console.log(`Hello, my name is ${this.name}. My param is ${parameter}`); } }
obj.greet("TWR"); obj.greet.call({name:"Jane"},"TWR"); obj.greet.apply({name:"Fabiana"},["TWR"])
http.createServer(function(req, res ){ res.writeHead(200, { ' Content-types ': ' text/plane ' } ) });
res.writeHead(200, { ' Content-types ': ' text/plain ' } ) We wrap the name in quotes; javascript does not require this but will allow it. Why? Some http names for the headers are not valid Javascript names.
english.js var greetings = require('./greetings.json'); var greet = function(){ console.log(greetings.en); }; module.exports = greet;
spanish.js var greetings=require('./greetings.json'); var greet = function(){ console.log(greetings.es); }; module.exports = greet;
We do not need the test to run, but we do want to run this while building the app. We can type npm install jasmine-node --save -dev
the -dev and when you look at the package.json file, you will see you have a devDependencies entry now. But, it is not needed to run the app. You can also find it in the node-modules.
Thus, we can use the index.js file to load multiple modules. If we have two files, english.js, and spanish.js, and we have greet in both. One is Spanish greet, and the other English greet. If we require greet in app.js, node will look for greet, then if it does not find it, it will look for an index.js file. In the index.js file we require both greets, we export both as an object.
var english = require('./english'); var spanish = require('./spanish'); module.exports ={ english:english, spanish:spanish };
var port = process.env.PORT || 3000; // so, if PORT does not exist, the PORT variable will be set to 3000.
var express = require('express'); var app = express(); var port = process.env.PORT || 3000 app.listen(port);
-- null if no error, otherwise will contain an object defining the error: This is a standard so we know in what order to place our parameters for our callbacks.
var fs = require('fs'); var greet = fs.readFile(__dirname + '/greet.txt', function(err,data){ console.log(data); });
This will limit the amount of data being read during the loop.
var fs = require('fs'); var readable = fs.createReadStream(__dirname + '/greet.txt',{encoding:'utf8'}); var writable = fs.createWriteStream(__dirname + '/greetWR.txt',{encoding:'utf8'}) readable.on('data',function(chunk){ writable.write(chunk); })
Back tics ! ` back tick ` This tells JS that this will be a template literal. . var name = "Terence" ; var greet = ` Hello ${name} ` ;
var greet = `Hello, my name is ${name}`; This is a template literal. It let me insert code without having to use the " + " that we use when we concatenate strings.
In most cases, you do not want this to be synchronious. This could block -
var greet = fs.readFile(__dirname + '/greet.txt', function(err,data){ });` After reading the file, then it will run the function(err,data) This is a error-first callback: The callbacks take an error object as their first parameter.
http.createServer(function(req,res){ res.writeHead(200, { 'Content-type':'text/html'}) var html=fs.readFileSync(__dirname + '/index2.htm','utf8') html = html.replace('{Message}', message); res.end(html); }).listen(1337,'127.0.0.1'); The problem with this is? It's Synchronistic! Blocking!!
var html=fs.createReadStream(__dirname + '/index2.htm','utf8') Remember that streams are just an idea of reading data a chunk at a time!. We are reading a file, but we can send the stream to any writeable stream! What is the writable stream that is already available? ttp.createServer(function(req,res){
var person = { firstname: '', lastname:'', greet:function(){ return this.fistname + '' + lastname } };
var john = Object.create(person);
var jsonParser = bodyParser.json([options]) so the body parser we just loaded, we can use this to get a function to handle json. app.post('/personjson', JasonParser,function(req,res){"Thank you"} ) The body will be the json object that we send converted into a javascript object.
var jsonParser = bodyParser.json( ) app.post('/personjson', JasonParser,function(req,res){"Thank you"} ) Now we just need to set up a json data : we can use jQuery to do this.
How do we get access to the module? We can use require('moment'). It will first look for something in the node core. If it does not find it, then it looks at other places. One of these places is node_modules.
var moment = require('moment'); console.log(moment().format()); Run this and we get a date: 2020-06-08T18:37:57-04:00
.call & .apply Any function can be called using .call( ). The difference is that .call(pass) whatever you pass from .call(var) will over write the "this" key word in your object.
var obj= { name : 'John Doe', greet:function(){ console.log(`Hello, my name is ${this.name}.`); } } obj.greet(); // prints John obj.greet.call({name:'Jane Doe'}); // prints Jane.
In javascript, we can write object literals: Name/Value pairs separated by commas and surrounded by curly braces. A shorthand way of creating an object.
var person ={ fname:"Terence", lname:"Doe", greet:function(){ console.log("Hello " + this.fname +" "+ this.lname); } } person.greet(); // you can also use brackets! console.log(person['fname']);
Primitive Values : A type of data that represents a single value. NOT an object. Everything that is NOT an object.
we have a value "a" and the value of "a" is setting in memory. When we pass "a" to a function, b=a what actually happens is a copy of "a" is created. "b" now has a new place in memory that holds a copy of the primitive value. This is called by value or passing by value.
In the case of POST / HTTP/1.1 Host:www.learnwebdev.net Content-type: application/x-www-form-urlencoded Cookie:num=4;page=2 { "username":'Tony', "password":"pwd" } username=Tony&password=pwd
when you have a form on the webpage and you hit the submit button, the browser forms a POST and the content type is Content-type: application/x-www-form-urlencoded -- but all this ends up meaning is that the query string is moved into the body of the HTTP request, so you do not see it in the URL because it is no longer a part of the URL, but it is the same data sitting in the body of the request.
Every object has a prototype, and you can assign properties and values to that prototype chain. Thus, when we call John.greet(); javascript will search down the prototype chain, until if fines a function greet.
you can see what the proto type is of any object by typing ; console.log(john.__proto__);
We said as long as the chunks are readable and writeable We can stream to anything that is a stream, like an internet connection. We are going to use zlip which is part of the node core.
zlip lets us implement a g-zip file. It is a compressed file. So, we will create a gzip stream. var gzip = zlib.createGzip(); what this does is creates a transformStream which is both readable and writeable. Every time a chuck is sent to it, it compresses that chunk.