The changing Landscape – HTML - The original intent – JavaScript



The changing Landscape – HTML - The original intent – JavaScript

0 1


BrownBag


On Github trolldown / BrownBag

The changing Landscape

Front End Web Development

Prashanth Batchu (Enterprise Web Development Team) November 20, 2013

Hello Everyone!
  • The goal of this Brownbag presentation is to talk about the changes that are currently happening with the way we approach Front End Web Development especially because of the prominence that JavaScript has achieved in the recent years and the elevation of Javascript's status as a core technology rather than just a helper scripting language
  • Lets take a look at the agenda.

Agenda

  • A quick walk through memory lane
    • HTML - The original Intent
    • Javascript's History
    • Rise of the Web
  • The way we use currently use JS
    • JS: A helper Library
    • jQuery & Co.
    • Limitations & Change of User & Business expectations
  • A new Paradigm
    • Emergence of new JS frameworks
    • Introduction to AngularJS
  • Challenges
  • Q&A
  • To provide a context for this presentation, we'll first need to go back in time and take a quick look at what HTML was originally developed for. We'll briefly discuss Javascript's evolution as well.
  • Then we will review the way we currently use Javascript. We'll explore why jQuery, DOJO and other libraries have come into existence. But the underlying issues with the Front End development haven't been accounted for. User and Business expectations have changed over the years. That created an opportunity for JS to take the center stage and play a crucial role in the web development stack, whose evolution is currently in progress.
  • Numerous javascript based projects have sprung up including Ember, AngularJS, Backbone etc. in the recent years. We will closely study Angular JS, a meta framework called neatly showcases the paradigm shift in the way we can use javascript.
  • We will talk about what AngularJS brings to the table, its core philosophy and way it addresses the problems that Front End developers have been facing because of the limitations of HTML. AngularJS takes a completely different approach while focusing on reusability, testability and maintainability. We will then discuss what this new paradigm means for all of us and the changes that we can expect.

HTML - The original intent

1993 The present
  • We have two webpages displayed here. One of these two pages has quite a bit of significance.
  • Can anyone tell me the page I'm talking about and why it is significant?
  • The page on the left is the first web page ever created! In 1993.
  • It's just a static html page with links to more pages. Nothing interesting
  • The page on the right shows an IDE/li>
  • Fast forward to 2013 and we now have a full blown IDE running inside a browser!
  • So you might be wondering what the problem is. We will get to that in a bit./li>
  • But the key takeaway from this slide is that HTML was originally designed to show static documents on the web and not much more.
  • Now lets take a quick look at the milestones of HTML5

HTML Milestones

  • 1989: Tim Berners-Lee invents the Web with HTML as its publishing language
  • Late 1994: The World Wide Web Consortium forms
  • November 1995: Vendors unite to form a new group dedicated to developing an HTML standard which will be dismantled in a couple of years since then
  • November 1995: Style sheets for HTML documents begin to take shape
  • December 1997: HTML 4.0 was published as a W3C Recommendation
  • January 2008: HTML5 was published as a Working Draft (link) by the W3C - Still a work in progress
  • September 2012: W3C proposed a plan[29] to release a stable HTML5 Recommendation by the end of 2014 and an HTML 5.1 specification Recommendation by the end of 2016
These milestones are familiar to us. So briefly speaking, HTML since its widespread adaption in the 90s hasn't changed much till 2008 till the inception of HTML5. I did not mention the failed xhtml branch as it has no significance anymore. Let's quickly review HTML5.

HTML5

What's new? HTML expanded to support new APIs, brings in additional markup and limited backward compatability. HTML5 brings in some new APIs, new markup. The number APIs implemented is varied between browsers.

Summarizing HTML5

  • Too little too late?
  • Necessary but not sufficient?
  • HTML5 - The broken promises?
HTML5 development has been chaotic so far. I guess these are some ways to summarize how the HTML5 development was handled so far. We need to review one more item to get to the crux of this Brownbag's topic. That item is JavaScript. Let's get to it right now.

JavaScript

  • Loosely typed, Expressive, Prototypal, dynamically typed
  • Has more in common with Lisp, Self and Scheme than with Java. It is Lisp in C’s clothing
  • Functions are first class objects with (mostly) lexical scoping
  • Class-free object system
  • Has a very powerful object literal notation
  • Ubiquitous in all modern browsers.
Here are some of the features of Javascript that need to be grasped before one attempts to make proper use of JavaScript. Except for borrowing many names and naming conventions from Java, it doesn't have much in common with Java. It in fact is closer to LISP than it is to Java. It is Lisp in C's clothing. JavaScript is loosely typed, very expressive, has prototypal nature, is dynamically typed and has a class free object system. In JavaScript, Functions are first class citizens which gives it an immense power and also troubles developers coming in from a Java background who are not fully familiar with Functional programming paradigm.

JavaScript Milestones

  • May 1995: Created in 10 days by Brendan Eich
  • 1996 - 1997: Taken to ECMA to carve out a standard specification. ECMAScript v2 in 1998, v3 in 1999
  • 2001: Douglas Crockford named and documented JSON (JavaScript Object Notation) – a Lisp-inspired idea to use JavaScript syntax to store data in text format.
  • 2005: Jesse James Garrett coins the term AJAX.
  • 2007: Webkit becomes the foundation of the mobile web
  • 2008: Rename ECMAScript 3.1 to ECMAScript 5 and drive the language forward using an agenda that is known as Harmony
  • 2009: Node.js - JavaScript on the server
  • 2009 to Present - Paradigm shift in the way we use JavaScript
The content on this slide is also mostly familiar to us. Introduction of JSON & AJAX have revolutionized the way we use JavaScript. Standardization of JavaScript has been problematic thanks to its proliferation over the years with various dialects and versions of ECMAScript, JavaScript and jScript floating around as all browsers differed in what version or dialect they supported.

Traditional uses of JavaScript

  • Realtime DOM manipulation
  • AJAX
  • Handling Browser Events
  • Limited Animation
This slide is all familiar to us. The way we traditionally used JavaScript over the years has been to enhance the user experience by catching user generated browser events like clicking a button and subsequently updating or modifying the DOM after either making an AJAX call or just by changing the way the UI looks without reloading the page. Simple usecases include everything from prevalidation of form data before it is shipped to server for final validation & processing to catching a button click event then perform an AJAX call and display the server returned data to the user without a page refresh. Pretty much anything dynamic in the browser has to happen with the support of JavaScript.

Rise of the Web

  • The Web Browser becomes Ubiquitous with HTML, CSS & JS as the De Facto technologies resisting any alternatives
  • Thin clients win over Thick clients
  • AJAX drive up demand for Desktop style web applications
  • Apple effectively pushes Flash out of existence
  • JavaScript stands its ground
  • User and Business expectations constantly push for more complex and interactive web apps
The Web Browser becomes Ubiquitous with HTML, CSS & JS as the De Facto technologies resisting any competition. Think clients win the Thick vs Thin battle with the demise of applet technology. Flash gets choked out of existence. JavaScript replacement technologies fail to achieve mainstream acceptance. And over the years as enterprises and businesses have embraced the browser making it the de facto mechanism to deliver the content to their audience and that pushed for increase in scope and complexity of web application progressively. But it has become a challenging environment for developing front end apps. The front end technologies just did not keep up with the pace. All the backend technologies kep evolving aggressively with the introduction Dependency Injection, subjective embrace of design patterns, evolved ecosystem of build and Continuous Integration tools. But the frontend pretty much remained the same over the years. The main reason for this is the browser. We have full flexibility in switching to a newer technology for the backend but not so much when it comes to the frontend. We just can't force the users to use a specific browser of our choice no matter how wise and meaningful the switch would be.

Browser Vs JavaScript

  • Browser proliferation with varied support for JS dialects create unique set of challenges for developing Web Apps
  • Increase in scope and complexity of web apps over time with the introduction of AJAX, severe limitations of HTML and a stale and stuck version upgrade process of HTML5 to support the development of highly interactive and catch up with the changes happening to JavaScript, Proliferation of JavaScript dialects among browsers, lack of adoption of suitable alternatives to JS have all led to rethink the way we perceive JavaScript
So how did we approach this problem before?

A Solution Kick the can down the road

  • Abstract away from JavaScript: jQuery, DOJO, Mootools etc.
  • Avoid the problem in its entirety: GWT, Vaadin, Opal, Dart, IronPython, IronRuby, HotRuby, Livescript etc.
So why doesn't Abstraction or avoiding the problem address the limitations of HTML?

Why doesn't Abstraction address the problems?

  • In an ideal world where browsers play nice, jQuery shouldn't have an existence. But it does exist to make Front End development less hellish for developers. jQuery fills some of the gaps occurred because of JS proliferation which should not have happened in the first place.
  • Abstraction limits
    • Reusability: As we end up tying the DOM (manipulation, attachment) to Business logic (eg: jQuery)
    • Testability: Limits our ability to test when business logic is tightly coupled with the DOM (IDs, Classes etc.)
    • Maintainability: No proper native development paradigm coupled with increasing business need for highly interactive and complex workflows and lack of adaption of proper design patterns increases the lines of source code without proper organization making it extremely difficult to maintain over time.
In an ideal world, jQuery shouldn't exist. Don't get me wrong. I'm all for jQuery and what it has managed to acheive in making front end developmemt less miserable. We all know how painful and time consuming it is to deal with browser enabling our apps to run the same way across different browsers. Not just that but abstraction also limits our ability to reuse, test and maintain apps as they become more and more complex and expand in scope.

Paradigm Shift

  • Declarative rather than Imperative suits Front End Development
  • Need a MV* pattern and a Modular approach to solve many of the maintainability and reusability issues
  • Ground up support for Testing
  • Embrace & Expand on but not shun HTML
  • Limit DOM manipulation whenever possible or avoid it completely or do it a controlled reusable way
The evolution of backend technologies provides some good insights to approach the problems plaguing the front end development environment. There is a lot that can be borrowed from the backend to the frontend like design patterns including MVC, Dependency Injection, build tools etc. while letting HTML evolve at a much faster pace than it is current rate of change. Also we talked about the increasing scope and complexity of front end apps. So why not borrow MVC pattern from the backend and apply it to the frontend to solve some of the maintainability and reusability issues? And for the same reasons why not find ways to support testing front end code from the ground up? Would employing the concepts of dependency injection help? Absolutely! Another failed attempt has been to shun or evade HTML and that did not end up well. HTML needs to keep evolving at a much faster pace to keep up. Also DOM manipulation using Event based programming should be limited to promote reusability and testability. So what has been the developer community's response in the past past few years to address some of these issues ?

Developer community's response

So the reaction is emergence of a plethora of frameworks adapting varied design principles and philosophies but the goal for almost all of these projects is to change the way we use and perceive javascript. Strategies to replace javascript haven't worked. So if you can't beat 'em, join 'em. By the way the same principle applies for Index funds for those who are financial geeks in the audience. Anyway, we got more listings in the next slide.

Compile To JavaScript

MVC Extension Frameworks

Module Loaders

Real-time

  • Meteor
  • Derby
  • SocketStream
  • Firebase + AngularJS

    Firebase + AngularJSWebsite

    Firebase is a scalable realtime backend that lets you build apps without managing servers. Firebase persists and updates JSON data in realtime and is best used in combination with a JavaScrpt MV* framework such as AngularJS or Backbone.
And thus Javascript is here to stay and is not going away anytime soon. If Javascript issues stock,I'd be all over it. It would be hotter than Apple's. Anyway it is almost impossible to talk about each and every one of these frameworks. By the time we are done with the first two in the list, three more new projects will have already sprung up. So let's pick one to study.
Angular JS represents one such framework which attempts to address some of the issues plaguing front end development. Angular JS represents one such framework which embraces this new paradigm shift. Actually all the frameworks listed in the previous slides embody similar goals but with different philosophies. So it is perfectly fine if one wants to try out Ember or Backbone or any other project. Each of these technologies have their own strengths and weaknesses but they all do bring a lot of value to the table. I personally believe that Angular promotes an organic solution to the existing problem by borrowing time tested design principles and practices from the backend and creating an End to End solution for developing Front end web apps. It has gathered a lot of attention and support from Developers in the recent years. Studying it will provide insights into some of the ways these frameworks attempt to solve some of the problems with abstraction. So what is Angular JS anyway?

Angular JS

“AngularJS is a structural meta framework for developing modern dynamic web applications”
  • AngularJS is a structural meta framework for developing modern dynamic web apps
  • Angular is what HTML would have been had it been designed for web applications.
  • It provides an End to End solution for developing front end apps.
    • It is a Meta Framework
      • What I mean by "meta" is that it gives a lot of wiggle room for developers to expand on its existing functionality. We'll talk about it a bit later
    • It Works well with other js libraries nicely including JQuery (If we need to). Let's talk about how it solves some of the issues that we previously talked about.

An End to End solution

  • Reusability: Using Directives and Services
  • Maintainability:
    • Modular Architecture (Module)
    • Supports MV* pattern: Controllers, Views (ViewModel - $scope, Services, Factories
    • Two Way Data Binding
    • Declarative style
    • Dependency Injection
  • Testability:
    • Everything is Dependency Injected.
    • Mocks provided for the framework by default
    • Testing support from the ground up using Karma/li>
  • Browser Support: Tested extensively against Safari, Chrome, Firefox, Opera, IE8, IE9 and mobile browsers (Android, Chrome Mobile, iOS Safari)
Angular borrows a lot of design practices from several backend technologies like Java, Spring and others. It supports a modular architecture in designing front End web apps using MV* design pattern. So in Angular you hear a lot about Modules, Controllers, Views and Services. All of these components are wired together using the Dependency Injection design pattern. Angular supports testing from the ground up. Since DI is supported, writing tests becomes much easier. You can use the mocks that come with the Angular source to bootstrap your test environment. There is also an eco-system of tools to perform build tasks, dependency management just like we use Maven or Gradle in the backend. Angular promotes Declarative style of programming for the frontend as opposted to an imperative style which is best suited for the backend. This reduces linking DOM with JS code.
//Module declaration
angular.module('shinyApp', ['global_service_1','global_service_2']);
//Service declaration
shinyApp.service('shinyService', function($resource, $q) {
});
  • A module acts as a container for other AngularJS managed objects.
  • A controller has a $scope variable which acts as the glue between the controller and the view to enable two way data binding.
Before we see checkout what's under the hood, lets take a high level view of how an Angular based App would be structured like and see how its components interact with each other. Here we have an Angular Client consuming a REST API. An Angular client can have one or more modules. A module acts as a container for other AngularJS managed objects (controllers, services, and so on) and manages their lifecycle. Here we have a view (an html partial), a controller and a service. A controller has a $scope variable which acts as the glue between the controller and the view to enable two way data binding. The Route maps each URL to a View (html partial) and a Controller.
//Controller declaration
shinyApp.controller('shinyCtrl', function($scope,shinyService) {
//Everything in $scope will be made available to the html partial
$scope.message = shinyService.getMessage();//'Hello World';
});
<!--HTML Partial -->
{{message}} <!-- outputs Hello World-->
  • When a URL is invoked, a new instance of its associated Controller is created.
  • This controller is injected with all of its dependencies(The service in this case) including a $scope variable.
  • The service interacts with the REST Api using $resource Angular service and returns the response to the Controller.
When a URL is invoked, a new instance of its associated Controller is created. The controller is injected with all of its dependencies(The service in this case) including a new child $scope variable inherited from the $rootScope. The service interacts with the REST Api using $resource and returns the response to the Controller. The view which is bound to the controller using $scope will now show the updated data coming in from the interaction with the REST api.

Angular supports Two way Data Binding

  • Data-binding: Automatic synchronization of data between the model and view components.
  • Treat the model as the single-source-of-truth in your application.
  • The view is a projection of the model at all times. When the model changes, the view reflects the change, and vice versa.
Those of you who have worked with Flex or WPF may be already familiar with Data Binding.It is very simple. You have a model (data) specific to your application and you bind this model to a template and let the templating engine generate the views for you.
  • Here I have a very simple model with a profile of Tony Stark and it's bound to two templates which generated the two views. Now the interesting part about this is that this is not a one time link between the view and the model. It is a live system where if I modify the model, the templating engine will observe this change and will update the view automatically. I don't need to go update the view every time the model changes. And it also works the other way around. So if you have two way data binding and you bind the model to the form like I have in the second view. If the user starts interacting with the form and starts changing the form content, the changes will be propagated automatically to the model. And because I have a second view bound to the same model, these changes will go back to the second view where it will be reflected automatically.
  • It can get more advanced if you start dealing with Arrays and Collections
Let's say I have an array of 3 superheroes and I bind it to a template using a repeating construct built into Angular. What I'm telling the templating engine to do is to iterate through all the elements of the array, tie each element to the template. What you get out of this is this generated view of 3 super herores. And its not a one time thing. Lets say you push a new object into this array or you remove an object from the array or simply modify the contents of the array, the changes will be automatically reflected in the view. You don't have to do anything to manage the view once the two-way data binding is enabled.
With data binding you can remove a lot of javascript code from your application. Because when you look at a typical application, about 70 to 80% of all the js is synchronizing the model with the view and updating the model with the changes in the view. All of this code can go away. So Angular teaches browser how to do data binding using existing api's. Google is actually creating a specification to propose this two way data binding feature to be built into next generation web browsers.

Directives

HTML can be very verbose sometimes. Let's take a simple example. Let's say that I would like to create a neat tab system in my application with Bootstrap CSS. In order to generate a simple component like this, I need to copy paste this chunk of html to get this view. This is not ideal. HTML has a limited set of vocabulary and often comes short when we want to build some basic components like Accordions or tabs natively. Also this is not maintainable. You have to copy/paste it again, change the div ids etc. If the template changes you need to go to all the places where it is used and change it.

Directives

So what I want in my html template is to specify a custom tag say "tab" and just tell the browser to render tabs. I want this page to have two tabs and each tab will have a title. You figure out what the underlying DOM structure needs to be generated. This is something that is supported by angular. This concept of reusable code is called Directives.
And its not just tabs. Think about all these components that you could build using this feature. You can also share it within/outside of your project. These components can be stateless or stateful.
So reusable components feature in Angular is built with existing JS & DOM APIs. It's available in all the browsers. And it is also being proposed to become native for all modern browsers. It's already been implemented in Chrome Dev versions.

Type in your Name

Here we have another simple example to demonstrate the two way binding of angular. This simple app doesn't use the angular's modular features for the sake of simplicity. If we take a look at the html source, we declared ng-app as a div attribute which implies that angular's scope is limited to this specific div. The input field has a ng-model attribute titled 'name'. We are again displaying the same by decorating name with flower brackets a couple of lines below. So the input box and this name decolared with flower brackets point to the same model behind the scenes. As we begin to type in the text box, we notice that the text next to "hello" gets updated. So What angular is doing behind the scenes as we start interacting with the text field is that it is updating the model in the javascript with the user changes. Since both the textbox and the text next to 'hello' subscribe to the same model, the changes made to the textbox will now be propagated to the text display next to Hello.

Declarative vs Imperative for the Front End

<div class="container" ng-controller="TextAreaWithLimitCtrl">
<span>Remaining: {{remaining()}}</span>
<textarea ng-model="message">{{message}}</textarea>
<button ng-click="send()">Send</button>
<button ng-click="clear()">Clear</button>
</div>
//Number of remaining characters - HTML
<span>Remaining: {{remaining()}}</span>
//Corresponding JS code
$scope.remaining= function () {
return MAX_LEN - $scope.message.length;
};
<!-- Disabling the button if the length is invalid -->
<button ng-disabled="!hasValidLength()" ...="">Send</button>
Declarative style of programming suits front end HTML development better. Imperative style is ideal for the backend but not so much for the frontend. let's understand it better with a simple example. Here we have a small message box. The simple requirements here are The Send button's disabled state must be properly managed The Remaining charecter length should be updated as the user continues to type. The code snippets show the declarative approach. The first snippet shows the html markup to generate the view. The flower brackets decorate the remaining() function. So the output of the remaining() function is displayed as the result. Similarly the message attribute's value is displayed in the next line. We will talk about how this two way data binding works in a bit. The buttons are decorated with ng-click attributes which are Angular's naive directives. They pretty much call their respective functions on upon button clicking. Angular promotes declarative style of programming for the front end.

Live Demo

Walkthrough a Web App with Angular

  • Brief introduction to the example Application
    • A simple CRUD app
    • Business use - Bill splitting between friends
    • Project goal - Promote Community Learning (Open Source)
  • The application that we are going to go through is a basic CRUD application. It's called Billrive. It is an open source project. The goal of this project is to promote community learning. This application is bascially a testbed for trying out new things. The link to it's GIT repository will be provided at the end. Please feel free to fork.

Walkthrough a Web App with Angular

  • Setup
    • Frontend - Angular JS, Bootstrap CSS, Angular Strap
    • Backend - Java EE, Spring MVC REST, JPA with Hibernate
    • Database - MySQL
    • Application Server - Tomcat (Neutral)
  • Now let's take a look at it's setup. The application is comprised of two parts. A Backend REST service and an AngularJS client. The frontend is primarily built upon Angular JS, Bootstrap CSS and Angular Strap.
  • The backend is a Java EE application built using Spring. The persistence layer is built upon JPA with Hibernate as its provider.
  • MySQL is the persistence store. Although the application can use any RDBMS data provider
  • The default Application server for the service is Tomcat although any Java Web container will do fine.

Walkthrough a Web App with Angular

  • Design & Arch
    • Frontend - MVC
    • Backend - MVC
    • Interface - REST
    • Data Transfer - JSON
  • Now about the basic architecture of the whole application, Both the frontend and the backend are basically built using the MVC pattern. The backend is a RESTful webservice built using Spring MVC. Data interchange between the service and the client is strictly done through JSON.

Walkthrough

  • Fire up the MySQL DB instance
  • Start Tomcat and deploy the service. Test an endpoint
  • Run the client
  • Use the app
  • Now about the basic architecture of the whole application, Both the frontend and the backend are basically built using the MVC pattern. The backend is a RESTful webservice built using Spring MVC. Data interchange between the service and the client is strictly done through JSON.

Environment - Debugging

Best Practices

  • Yo scaffolds out a new application, writing your Grunt configuration and pulling in relevant Grunt tasks that you might need for your build.

  • Grunt is used to build, preview and test your project, thanks to help from tasks curated by the Yeoman team and grunt-contrib.

  • Bower is used for dependency management, so that you no longer have to manually download and manage your scripts.

Resources

Challenges

  • Functional Thinking: JavaScript name sounds close to Java but that's where the similarities end. Support of Closure and other Functional characteristics
  • Understanding its bad parts
  • Functions are first class citizens
  • Getting acquainted with the new Ecosystem
Working with these modern Javascript libraries and frameworks require using JavaScript in its native form. I come from a Java background and the transition hasn't been a smooth ride for me. When dealing with JavaScript, not thinking in a Functional way is bound to give you a rough ride. Also as expressive JavaScript is, it is plauged with a lot of bad parts. I recommend grabbing a copy of either "JavaScript: The Good Parts" or "JavaScript Enlightenment guide".It is imperative to steer away from these bad parts and embrace functional thinking. And finally JavaScript is here to stay. Being in denial is not going to help.

References will be made available along with these slides

Q&A