WebFund 2016W Lecture 13

From Soma-notes

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
  • 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() and insertMany() that seem to do the same thing
    • For what we want to do insert() will work
  • 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 of g()
  • 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 of findCallback that have their own copies of request and response, therefore one version of findCallback 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 or window
  • 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
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

downloadable version

// 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);