WebFund 2016W Lecture 13
Video
The video from the lecture given on March 1, 2016 is now available.
Notes
In lecture
Lecture 13 ---------- To get help with assignment 4, look at Assignment 5 from Winter 2015. closures DOM - document object model - set of JavaScript objects for accessing the current page in the browser client-side JS can access the DOM (data structures representing the current web page) server-side JS can access the operating system client-side JS is *limited* in its access - because such access is dangerous - ANYONE can run JavaScript in your browser - so, JavaScript in the browser is sandboxed execution sandbox is an environment for running untrusted programs - sandbox limits access and resources Client-side JavaScript has no native way to (well, it used to...) - access local files - open network connections - run multiple threads - access other windows/programs Originally JavaScript was so limited it could do no background processing - could only run when the page was loaded or when the user acted Microsoft messed it up - Outlook Web Access - they built an ActiveX control which implemented XMLHttpRequest() - but really, it was a way to do GETs and POSTs in the background - other browsers implemented the API natively Now you could update data in a web page without reloading the page
Student Notes
storelogline.js and storelogs.js
- To use storelogline.js:
- Find an entry from an existing log file and copy the line
- Run storelogline.js with the copied line pasted after the script name as command line parameters
- Optionally, verify that the line was entered in the database by typing the following with the Mongo client:
mongo
use log-demo
db.logs.find()
Writing storelogs.js
- We can use the code from storeloglines.js to start building the storelogs.js script for tutorial 5
- To read in a file specified in the command line, you do
var data = fs.readFileSync(process.argv[2], ‘utf-8’);
- You use
process.argv[2]
because in the terminal your third argument is going to be the file to read
- You use
- To split the data into lines, yo do
var lines = data.split(‘\n’);
- To parse the lines and store them into an array, you can do something like:
var entries = [];
int i; entry, fields, j;
for(i=0;i<lines.length; i++) {
if(lines[i] &&lines[i]!==null) {
field=lines[i].split(‘ ‘); //this is used to split the lines at index i wherever the spaces occur
console.log(split); //when this is printed you’ll see that it splits between all the spaces as well—>you can regular expression to fix this but we fixed it through the while loop
entry={};
j=0;
//Used to delete the spaces
while(j<field.length) {
if(field.lenght[j]===“ “) {
field.splice(j, 1);
}else{
j++;
}
}
console.log(field); //—>this prints the logs out without the spaces
entry.date=field[0] + “ “ + field[1]; //Than you start populating the array
entry.time=field[2];
entry.host=field[3];
entry.service=field[4].slice(0,-1); //the program will have an error here without the if statement above
entry.message=filed.slice(5).join(‘ ‘);
//to store in to the entries ( the array )
entries.push(entry);
}
}
- To insert into the database you don’t need a loop to iterate. You can use the
collection.insert()
method which can take an array (entries) as the argument to insert- API’s have documentation and they change because there’s also
insertOne()
andinsertMany()
that seem to do the same thing - For what we want to do
insert()
will work
- API’s have documentation and they change because there’s also
- For querying the database (assignment 4), there is a trick
- There are previous assignment solutions that can help you.
- It's the previous assignment from last year’s assignment 5
- Note that when using special characters like [] and () in regular expression, you will need to use a backslash to escape them
JavaScript Closures
- JavaScript closures are about nesting functions
- For example:
var f = function(x) {
function g(y) {
return x+y;
}
return g; //The function g can see x
}
var q = f(7);
var h = f(12);
console.log(“q = “ +q(4)); //prints 11
console.log(“h(4) = “ + h(4)); //Prints 16
- This gives different answers because
x
is different in two two instances ofg()
- You cannot do things like this with C
- In examforms we have an app.get for list and we have a function in it that has a callback called
findCallback()
- This callback function has access to the request and response objects because they were in scope at the location where the callback function was defined
- To have
findCallback
have access to request and response you just need to create different instances offindCallback
that have their own copies of request and response, therefore one version offindCallback
will have one request and on another call it will have another request
- Closure is a concept you need to understand because it’s very handy
Client-Side JavaScript
- In JavaScript we’ve been doing everything on the server side so far
- Using the browser dev tools, you can go to console and play around in it. Its almost like the Node environment in a terminal but with some missing features
- In the browser there is no
require()
- In the browser the unit is the page but in the server its the file
- You can access objects representing the page by typing
document
orwindow
- When you load a webpage, it can load and run scripts
- By running JavaScript within the browser, you can write code that has access to the webpage (in particular, the DOM)
- The DOM (Document Object Model) is a tree-like structure of objects representing the HTML elements of the page
- By running JavaScript within the browser, you can write code that has access to the webpage (in particular, the DOM)
Differences Between Client-Side and Server-Side JavaScript
- Client-side JavaScript can access the DOM (data structure repressing the current web page)
- Server-side JavaScript can access the operating system
- In client-side JavaScript, you can’t access everything... It's *limited*
- That’s because such access is dangerous, the code could be coming from ANYONE
- ANYONE can run JavaScript in your browser and you don’t want this code messing with your system
- The browser is designed to protect your system from bad JavaScript, so JavaScript in the browser is sandboxed
- An execution sandbox is an environment for running untrusted code
- The sandbox limits access and resources
- Client-side JavaScript has no native way to:
- Access local files
- Open network connections
- Run multiple threads
- Access other windows/programs
- The model of client-side JavaScript was that it should be limited
- Originally JavaScript was so limited that it could do no background processing
- It originally could only run when the webpage was loaded or when the user acted
- It was singly threaded so you had to limit your execution
- Microsoft messed it up (in particular, the Outlook Web Access team messed it up)
- They built an ActiveX control which implemented XMLHttpRequest() —> an object that would send a GET or a POST request and would bring back a document that is assumed to be XML
- But more importantly, it was a way to do GETs and POSTs in the background
- Other browsers implemented the API natively
- Now you could update data in a web page without reloading the page
- Google really ran with this (with gmail, google maps, etc)
- Client-side JavaScript is the same JavaScript we have been working with except it has access to a webpage now but you access the things you can access the exact same way
- If you want to change how the current page looks or works you can type JavaScript directly into the browser console (it uses a read-eval-print loop which will affect the page)
Code
nested.js
var f = function(x) {
function g(y) {
return x + y;
}
return g;
}
var q = f(7);
var h = f(12);
console.log("q(4) = " + q(4));
console.log("h(4) = " + h(4));
https://jsfiddle.net/Manouchehri/jy5793dd/
storeLogs.js
// storeLogs.js
//
// node storeLogs.js <logfile>
//
//
// The log messages in the file should be of the format:
// <month> <day of month> <24-hour time in hh:mm:ss> <host> <service name[pid]>: Actual message
//
var mc = require('mongodb').MongoClient;
var fs = require('fs');
var data = fs.readFileSync(process.argv[2], 'utf-8');
var lines = data.split('\n');
var entries = [];
var i, j, entry, field;
for (i=0; i<lines.length; i++) {
if (lines[i] && lines[i] !== '') {
field = lines[i].split(' ');
entry = {};
j = 0;
while (j < field.length) {
if (field[j] === "") {
field.splice(j, 1);
} else {
j++;
}
}
entry.date = field[0] + " " + field[1];
entry.time = field[2];
entry.host = field[3];
entry.service = field[4].slice(0,-1);
entry.message = field.slice(5).join(' ');
entries.push(entry);
}
}
// entry.date = process.argv[2] + " " + process.argv[3];
// entry.time = process.argv[4];
// entry.host = process.argv[5];
// entry.service = process.argv[6].slice(0,-1); // drop the trailing colon
// entry.message = process.argv.slice(7).join(' ');
var db;
var reportInserted = function(err, result) {
if (err) {
throw err;
}
console.log("Inserted the following log record:");
console.log(result.ops);
db.close();
}
var connectCallback = function(err, returnedDB) {
if (err) {
throw err;
}
db = returnedDB;
db.collection('logs').insert(entries, reportInserted);
}
mc.connect('mongodb://localhost/log-demo', connectCallback);