Modern Web Development with JavaScript – Rohit Kalkur – History of JavaScript



Modern Web Development with JavaScript – Rohit Kalkur – History of JavaScript

0 1


modern-web-dev

Course material for my class Modern Web Development w/ JavaScript

On Github rovolution / modern-web-dev

Modern Web Development with JavaScript

Rohit Kalkur

Prerequisites

  • Understanding of how a web application works
  • Web application development experience in another language/framework (Java Spring, Ruby on Rails, PHP etc...)

Course Objectives

  • JavaScript Foundations
  • Lab
  • Client-server Interaction
  • DOM Manipulation
  • Lab
  • Lunch?
  • Application Architecture
  • Backbone.js
  • Angular.js
  • Lab - Choose either Backbone.js or Angular.js lab
  • Advanced Concepts
  • Wrap Up

History of JavaScript

  • Created by Netscape engineer Brendan Eich in April 1995
  • First called Mocha and then LiveScript
  • Has nothing to do with Java despite the name!

How It Works

  • HTML page has <script></script> tags where JavaScript code is written
  • JavaScript is an interpreted language, so the code immediately executed after being loaded into browser
  • JavaScript can also be loaded in from external files
<!DOCTYPE html>
<html ng-app>
  <head>
    <script>
    	alert("Running this JavaScript!") //Immediately triggers an alert box when the page is loaded 
    </script>
    <script type="text/javascript" src="main.js"></script> <!-- Loads in an external script -->
  </head>
  <body>
  </body>
</html>

JavaScript - Primitive Data Types

/* Variable Initialization/Declaration */
var myNumber = 5;
var myString = "myString";
var myBoolean = false;

/* Print Output To Debug Console */
console.log("my number is " + myNumber); // Output: "my variable is 5" 
console.log("my string is " + myString); // Output: "my string is myString"

console.log( typeof myNumber ); // Output: "number"
console.log( typeof myString ); // Output: "string"
console.log( typeof myBoolean ); // Output: "boolean"

JavaScript - Objects

/* Object Initialization/Declaration */
var obj = {
	"prop1" : 5,
	prop2 : "value of property 2"
};

obj.prop3 = false; // Add a property to an already defined object

console.log( obj.prop1 ); // Output: 5
console.log( obj["prop2"] ); // Output: "value of property 2"

console.log( typeof obj ); // Output: "object"

JavaScript - Arrays

/* Array Initialization/Declaration */
var myArray = [1, 3, 4];

myArray.push(5); // Appends 5 to myArray
myArray.pop(); // Remove the last value in the Array and returns it
myArray.length; // Returns the number of elements in the Array

/* Array is a type of object */
console.log( typeof myArray ); // Output: "object"

JavaScript - Boolean Logic

/* Basic Comparison Operators */
var a = 1;
var b = 2;

console.log( a > b ); // Output: false
console.log( a < b); // Output: true
console.log( a <= 1 ); // Output: true
console.log( a >= 1 ); // Output: true


/* Strict vs Loose Type Checking */
console.log( 0 == false ); // Output: true (loose check)
console.log( 0 === false ); // Output: false (strict check)
console.log( 0 != false ); // Output: false (loose check)
console.log( 0 !== false ); // Output: true (strict check)

JavaScript - Conditionals

/* If-Else Statement */
var age = 15;

if(age < 21) {
	console.log("You CANNOT drink legally in the United States!");
	console.log("Go drink a soda!");
} else if(age === 21) {
	console.log("Its your first of being able to drink alcohol legally!");
	console.log("Be responsible!");
} else {
	console.log("You are older than 21.");
	console.log("Still be responsible!");
}
// Output:
// console.log("You CANNOT drink legally in the United States!");
// console.log("Go drink a soda!");

/* Ternary Statement */
var val = (0 <= 15) ? "less than or equal to" : "greater than";
console.log(val); // Output: "less than or equal to"

JavaScript - Loops

/* For loop */
for(var i = 0; i < 5; i++) {
	console.log(i);
} 
/* Output: prints the numbers 0-4 */



/* While loop */
var i = 0;
while (i<5) {
	console.log(i);
	i++;
} 
/* Output: prints the numbers 0-4 */



/* Loop through object properties */
var myObject = { prop1 : 1, prop2 : 2, prop3 : 3 };
for(var key in myObject) {
	console.log("key: " + key + ", value: " + myObject[key]);
} 
/* Output: prints each key, value pair
	"key: prop1, value: 1"
	"key: prop2, value: 2"
	"key: prop3, value: 3"
*/

JavaScript - Functions

/* Function Initialization/Declaration */
function myFunction() {
	if(arguments[0]) {
	     console.log("This is my function with arg " + arguments[0]);
	} else {
	     console.log("This is my function!");
	}
}

myFunction(); // Output: "This is my function!"
myFunction(1); // Output: "This is my function with arg 1"

var mySecondFunction = function(arg) {
    console.log("This is my other function with arg " + arg);
};

mySecondFunction(2); // Output: "This is my other function with arg 2"

(function() { 
    console.log("Immediately Invoked Function Expression (IIFE)"); 
})() // Output: "Immediately Invoked Function Expression (IIFE)"

// Can add functions as properties to an object
var myCoolObject = {};
myCoolObject.printFoo = function() {
	console.log("Foo");
};

JavaScript - Context

var user = {
	name : "Al Grasso",
	printName : function() {
            console.log("Username: " + this.name);
	}
}
user.printName(); /* Output: "Username: Al Grasso" */

JavaScript - Prototypical Inheritance

/* Base prototype */
var fruit = {
  "color" : null,
  "shape" : null,
  "price" : 1.50
}

/* Orange constructor */
function Orange() {
  this.color = "orange";
  this.shape = "round";
  this.makeJuice = function() { 
     console.log("Made orange juice!");
  }
}
Orange.prototype = fruit;

/* Bananas constructor */
function Banana() {
  this.color = "yellow";
  this.shape = "long curving cylinder";
}
Banana.prototype = fruit;

var myOrange = new Orange();
var myBanana = new Banana();

console.log(myOrange.color); // Output: "orange"
console.log(myBanana.color); // Output: "yellow"

console.log(myOrange.price); // Output: 1.50
console.log(myBanana.price); // Output: 1.50

myOrange.makeJuice(); // Output: "Made orange juice!"
myBanana.makeJuice(); // TypeError: Object #<Banana> has no method 'makeJuice'

console.log( myOrange instanceof Orange ) // Output: true
console.log( myOrange instanceof Object ) // Output: true
console.log( myOrange instanceof Banana ) // Output: false

JavaScript - Prototypical Inheritance

JavaScript - Scope

  • Established within each function
  • 'var' keyword scopes variable to the function it is contained within
  • If reference not found in current scope, the above scope is checked
var a = 1;
function funcOne() {
    a = 2;
}
funcOne();
console.log(a); // Output: 2


var b = 1;
function funcTwo() {
    var b = 2;
}
funcTwo();
console.log(b); // Output: 1


function funcThree() {
	function funcFour() {
              console.log("Four");
	}
	funcFour();
}
funcThree(); // Output: "Four"
funcFour(); // ReferenceError: funcFour is not defined

JavaScript - Hoisting

function printA() {
	console.log(a);
	var a = 1;
}
printA(); // Output: Any guesses? Try inputting it into the console




printNumber(4); // Output: "The number is 4"
function printNumber(num) {
	console.log("The number is " + num);
}



printFoo(4); // TypeError: undefined is not a function
var printFoo = function(foo) {
	console.log(foo);
}

JavaScript - Exception Throwing/Handling

function throwError(message) {
	throw Error("ERROR: " + message);
}

try {
	console.log("This will print to the console");
	throwError("You've got problems!");
	console.log("This will not print to the console");
} catch(error) {
	console.log(error.message); // Output: "You've got problems!"
}

JavaScript - Element Selection & Event Binding (via JQuery)

/* 
	Select the HTML element with id = element1 & bind a click event to it 
*/
$("#element1").on('click', function(e) {
	e.preventDefault();
	console.log("clicked on element1!");
});

/* 
	Unbind the 'click' event from all elements with the class tag 'listing' 
*/
$(".listing").off('click');

Reminders

  • Always scope your variables!
  • Everything except the primitive data types (number, boolean, string) is an object!
  • use null (instead of undefined) to mean 'having no value'
  • Always use strict comparison operators!

Lab Time - JavaScript

Click to begin lab

JavaScript Back In the Day

JavaScript Today!

  • As browsers have evolved over time, so has JavaScript feature set
  • More application logic now being done on the client-side itself
  • Primary benefits are to speed and performance

HTML

  • HyperText Markup Language
  • Markup language for web browsers
  • Used to define structure and layout for web pages

DOM

  • Document Object Model
  • API for interacting with HTML markup as objects
  • HTML is just text, DOM is what we use to interface with it
  • Often times the terms (HTML, DOM) are used interchangeably

JSON

  • JavaScript Object Notation
  • Data format based on JavaScript objects
  • Note: Keys must be double quoted!
  • Benefit: Easy to work with in JavaScript!
{
	"key1" : 1,
	"key2" : "two",
	"key3" : [1, { "key" : "value" }],
	"key4" : true
}

HTTP

  • Hypertext Transfer Protocol
  • Method of communicating between client and server sides
  • Client sends Request, server comes back with Response
  • Request consists of info such as:
    • Path '/path/to/go/to'
    • Method GET
    • Parameters Key-value pairs

AJAX

  • Asynchronous JavaScript and XML
  • Retrieve data from server via HTTP requests
  • Only update parts of the view as necessary

REST

  • Representational State Transfer
  • Design for communicating with server-side via HTTP to manipulate back-end data objects
  • Uses 4 HTTP methods:
    • GET - Retrieve a resource
    • POST - Create a resource
    • PUT - Update a resource
    • DELETE - Delete a resource

REST

  • Example: I want to retrieve the list of users
  • Request: GET '/users'
  • Response: JSON object
[
    {
        "id" : 0,
        "username" : "agrasso",
        "email" : "agrasso@mitre.org",
    },
    {
        "id" : 1,
        "username" : "rkalkur",
        "email" : "rkalkur@mitre.org",
    }
]

REST

  • Example: I want to delete the user with id 1
  • Request: DELETE '/users/1'
  • Response: JSON object
{ "message" : "User rkalkur was deleted!" }

Broswer Developer Tools

  • Built into all major browsers
  • Allows you to:
    • inspect DOM elements
    • debug JavaScript
    • track incoming/outcoming HTTP requests
  • Extremely useful when developing JavaScript!
  • To access Chrome Developer Tools, right-click and go to "Inspect Element"

Traditional Application Structure

Single Page Application (SPA)

Lab Time - Client-Server Interaction

Click to begin lab

  • AJAX requests made to REST API to manipulate back-end data resources
  • Only individual pieces of the DOM are updated as needed
  • No complete page reload!

Benefits of SPA Architecture

  • View rendering/updating all done on the client-side itself!
  • Less requests to the server-side = a faster application!

JavaScript Client-Side Frameworks

  • Allows developer to neatly structure client-side codebase
  • Provides a predefined, out-of-box structure (that can be extended if need be)
  • Popular frameworks include:

Backbone.js

  • Created by Jeremy Ashkenas
  • Client-side code separated into Models, Collections, and Views

Backbone.js - Model

  • Representation of back-end data resources
  • Responsible for interacting with back-end via REST API
  • Triggers events when changed
var Employee = Backbone.Model.extend({});

/* Create instance of Employee */
var ceo = new Employee({ name : "Al Grasso" });

Backbone.js - Collection

  • Set of data models
  • Can also manipulate resources via REST API (fetch all models, create model)
  • Triggers events when models are added or removed
var EmployeeList = Backbone.Collection.extend({
   model: Employee,
   url: '/employees'
});

/* Create instance of EmployeeList */
var employees = new EmployeeList();

/* Bind a callback fn to employee's add event */
employees.bind('add', function() {
   console.log("Employee was added to employees");
});

/* Fetch list of all employees from server */
employees.fetch(); // Sends HTTP request - GET '/employees'

Backbone.js - View

  • Responsible for rendering, updating, and event handling on a section of the DOM
  • Associated with a model or collection (can bind to events)
var EmployeeListView = Backbone.View.extend({
    events : {
    	"click li" : "triggerEmployeeClickedMsg" // View event binding
    },
    initialize : function() {
        this.listenTo(this.collection, 'reset', this.render);
    },
    render : function() {
        var thisView = this; // Store view context in thisView

        thisView.$el.empty(); // Clear the existing list

        // Add each employee to the list		
        _.each(thisView.collection.models, function(employee) {
            var employeeListing = "<li>" + employee.get('name') + "</li>";
            thisView.$el.append(employeeListing);
        });
    },
    triggerEmployeeClickedMsg : function() {
    	alert("Employee listing was clicked!");
    }
});

/* Create instance of EmployeeListView */
var employeeListView = new EmployeeListView({
	el : 'ul#employeeList' // DOM element that view will correspond to
});

Templating Engines

  • Problem: In dynamic, data-driven applications, we are contantly adding/updating/removing different parts of the DOM
  • Need a way to render data-driven HTML views on the client side without page-refresh
  • Solution: Client-side templating engines!

Templating Engines

Implementations:

<script id="employeeListingTemplate" type="text/template">
  <li class="employee-listing">
    <div class="name"><@= name @></div> <!-- Outputs the 'name' property of the object passed to the template rendering -->
    <div class="email"><@= email @></div>
    <ul class="projects">
	  <@ _.each(projects, function(project) { @> <!-- Can embed code into template if need be -->
		  <li><@= project.name @></li>
	  <@ })  @>
    </ul>
  </li>
</script>

Templating Engines

/* JS Code */
var employeeListingTemplate = $("employeeListingTemplate").html(),
    employeeObject = {
           "name" : "Frank Johnson",
           "email" : "fjohnson@superdupercorp.org"
           "projects" : [
                { "name" : "The Super Duper Project" },
                { "name" : "The TOP SECRET Super Duper Project" }
            ]
	},
	compiledTemplate = _.template(employeeListingTemplate, employeeObject);
	// NOTE: You can now append 'compiledTemplate' to any part of your DOM

Lab Time - Backbone.js

Click to begin lab

Backbone.js - Pros

Backbone.js - Cons

Developer is responsible for:

  • Dereferencing unused objects
  • Cleaning up event bindings
  • Keeping view and data models synchronized (boilerplate code)

Angular.js

  • Created by Google
  • Automatically synchronizes view with data model (two-way data binding)

Angular.js - Template

<!doctype html>
<html ng-app>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
  </head>
  <body ng-controller="UsersCtrl">
   <ul>
  	  <li ng-repeat="user in users">
  	    <div class="name">{{ user.name }}</div>
  	    <div class="email">{{ user.email }}</div>
  	  </li>
   </ul>
  </body>
</html>

Angular.js - Controller

  • Responsible for application logic
  • Attach properties to $scope object
function UsersCtrl($scope, Users) {
   $scope.users = Users.query();
}

Angular.js - Resource

  • Allows user to interact with with server-side resources via REST
  • Injected into a controller as a 'service'
  • Can be extended if need be
$resource('/users');

Lab Time - Angular.js

Click to begin lab

Angular.js - Pros

  • Template Filters
  • HTML Directives (HTML tags with customizable behavior)
  • Dependecy Injection
  • Uses a smaller version of JQuery (JQuery lite)
  • Naturally supports unit testing
  • Less boilerplate code = smaller JS code base!

Angular.js - Cons

Steep learning curve!

Test Driven Development

  • Write a failing test - given an this input, I expect this output
  • Implement functionality to pass the test
  • Tests serve as 'blueprint' for functionality

Test Driven Development

Pros:

Clearly defined interfaces Fewer bugs Faster development time

Test Driven Development

Popular Testing Frameworks:

Jasmine BDD Mocha

Module Loading

  • Problem: All code stored in a single file (typically called app.js or main.js)
  • Can leads to global namespace conflicts
  • Difficult to test individual components of codebase
  • Becomes tough to read code!

Module Loading

  • Solution: Separate code into individual files - modules
  • Improves testability and performance
  • Popular implementations:

CoffeeScript

  • Alternative syntax that compiles down into JavaScript
  • Includes cool features such as:
    • more verbose, English-like syntax
    • default parameter assignment
    • O.O.P. class structure
  • Click here to read more

JavaScript on the Server-side - Node.js

  • Runs on the V8 JavaScript engine - same as Chrome
  • Non-blocking I/O via callbacks
  • Persistant communication channel between clients and server

About the Textbook

  • By Douglas Crockford (the father of JSON)
  • Discusses the "good" and "bad" parts of JS
  • Describes best practices for writing clean, maintainable JS
  • A must read for anyone writing lots of JS!

Thank You all for attending!

I hope you've been inspired to go forth and create cool web apps!