Single Page Applications (SPA) 2.0
- Push the limits of what’s possible on the web
AngularJS, RequireJS , Polymer, AMD, ES6 , Gulp, Dependency Injection, JavaScript Patterns, Functional Reactive Programming, OAuth, Promises ,Generators
4. Gulp - Task Runner
• The streaming build system. No more temp files.
• Gulp replace Grunt.
– Install: npm install -g generator-gulp-angular
– Run: yo gulp-angular [app-name]
– Run gulp for building and gulp watch for preview
gulpfile.js
5. Gulp and its NPM packages
• Built-in preview server with LiveReload, file watcher
• CSS Pre-processing : SASS, Bourbon Mixins
• CSS Autoprefixing : add vendor prefixes
• JSHinting, CSSLinting : lint your scripts, CSS
• JS Transpilers: ES6 ES5
• Awesome Image Optimization, WebP
• AMD/RequireJS Support
• Concatenation/Optimization, Minification, uglify
• Automatically wire-up dependencies installed with
Bower (when gulp watch or gulp wiredep)
8. Code Organization
• Adopt De Facto Standards
– Yeomen generated project structure
– Rapid prototyping using scaffolding generators
• Modularity: Organize your files by Feature not by Type
– Modules are independent WebApp functionality that developers can
work in parallel
– Isolate complexity into separate pluggable modules
– In an AngularJS context, modularization is organization by function
instead of type.
• Everything that gets deployed is in the app directory.
• Everything outside of the app directory is for
development
14. Testability
Why do you need to write tests?
– Because you’re not Chuck Norris.
Unit Testing
Karma: Spectacular Test Runner using real browsers!
– Jasmine: behavior-driven development framework for
testing JavaScript code.
– Mocha: Simple, flexible JavaScript test framework.
PhantomJS: Headless Testing
Integration Testing
– Protractor: AngularJS E2E Testing Framework
gulp test command transpile ES6 tests and perform all unit and integration tests
User story: “As a user, when I login to my app, I am taken to the dashboard page.”
15. ECMAScript 6.0
You Can’t Afford to Avoid ES6
Author In ES6, Transpile To ES5 As A
Build-step: Gulp Workflow
16. Traceur & Polyfills
Traceur and Shim/Polyfill makes it possible to use
tomorrows technology now!
– Traceur is a JavaScript.next JavaScript.now compiler
– “A polyfill is a piece of code (or plugin) that provides the
technology that you, the developer, expect the browser to
provide natively. Flattening the API landscape if you will.”
( from Remy Sharp blog)
Traceur provide ES6 that are not available in any browser yet.
Polyfill provide HTML5/ES6 features that are not available in some of the
browsers yet.
19. Promises
Promises are useful when you want to represent the outcome of an
action or a value that will be available at some future time.
– It is an easy way to avoid writing the Pyramid of Doom
– Function return a promise - no more callback parameter
– A promise represents an eventual outcome
– Promises can be pending, fulfilled or rejected
– they are only resolved once;
– Guaranteed to always be async.
– Promises can be chained. Re-tryable
– Promises as first-class objects
– “then-able” objects. then() method returns another promise and you can
return data from the callback to the next promise in the chain.
– A deferred is an object representing work that is not yet done and a
promise is an object representing a value that is not yet known.
Promise Combinators:
Promise.all([p1,p2,p3]) , Promise.race([p1,p2,p3]) , Promise.any([p1,p2,p3])
23. Promise Chaining
Asynchronous Control Flow with Promises
Promises are a replacement for Callbacks to help you deal with composition of multiple async
operations while also making error handling simpler in some cases.
24. What's the Big Deal with Generators?
"First-class coroutines, represented as objects encapsulating suspended execution contexts
(i.e., function activations)”
Allows suspension of a function's execution until resolved - everything else outside of that
execution continues. Higher-order functions
Uses a yield statement instead of a return to report values.
The essence of generator is controlling the suspension of code execution. Caller control execution
of code in Generator function.
Use Cases
• Infinite iterator : Good for representing infinite sequences. Generator return iterators.
• Non-blocking I/O : When we don't yield execution, we're blocking.
• Demand-driven: functions can interactively yield partial results as soon as available.
• Lazy Sequences: We can rewrite lazy version of Underscore.js using Generators. Since
filter and map return generators, nothing happens until reduce. You can get benefits of
declarative functional data manipulation without the performance and memory
downsides of intermediate arrays.
• Run-to-completion(RTC) is a scheduling model in which each task runs until it either
finishes, or explicitly yields control back to the scheduler.
• Flow Control: you can actually pass data back in to the generator, causing yield to either
return a value or throw an exception inside the generator body.
• Synchronously looking Asynchronous code: “Async functions are a thin sugar over
generators and a spawn function which converts generators into promise objects”
25. Generators Use case Scenarios
This is a big deal: generators finally provide us with a pseudo-synchronous syntax that doesn't
break run-to-completion semantics, doesn't require transpiling, and doesn't require callbacks.
Basic Examples Control Flow
Parallel Loops
28. AOP in JavaScript
• ES6 Proxies and Angular Decorators enable
augmenting new behaviors to existing JS Objects
and classes at runtime.
• Can be used along with Traceur’s Annotations (ES6+)
to add cross-cutting concerns by scanning
annotations during application bootstrap process.
• Angular 2.0 Dependency Injection will adopt this
approach.
• Retry aspect has been implemented using this
technique in SPA Starter Kit.
30. Functional Programming
What is FP?
A style which utilizes HOFs and minimize side effects.
Why FP?
Parallelization , Concurrency , Lazy evaluation
• Function composition
– E.g. collection.filter { x -> x > 5}.map{ x -> x * x}
– Data1 => function1 => data2 => functions2 => data3 => ...
– The only requirement is F1’s output type should match to F2’s input type
– Solution : Curried functions , Monads
• No shared mutable state
– Pure functions don’t change state
– Functions without side-effects (mutability)
– Functions are Deterministic. Data is immutable.
Imperative Programming
Functional Programming
31. Easy to change implementation.
With FP, Internal Iteration implementation can be changed: forEach => parallel forEach
1,000,000 users?
32. Functional Reactive Programming
FRP is all about effectively processing event streams without explicitly managing state.
Modern code
var a = 10;
var b <= a + 1;
a = 20;
Assert.AreEqual(21, b);
Ancient code
var a = 10;
var b = a + 1;
a = 11;
console.log(b);
“We don't assign variables, we express them, and they don't represent discrete
values, they represent a value that changes over time.”
a = b + c becomes var a = function (b,c) { return b + c }
Imperative Programming output => 11
Relative Programming output => 21
a := b + c ; meant a always equals b plus c, at any
time
Similarities with observer pattern
Observer pattern commonly describes data-flows between whole objects/classes, whereas FRP could
target the members of objects/classes. Observer pattern has limitations like Unpredictable order, Leaking
listeners, Threading issues, Messy State, Compositionality, Accidental recursion etc.,
Similarities with 2-way data binding
Models are updated with manual communication , in FRP they react to events
http://www.reactivemanifesto.org
33. FRP Terminology
Time-varying Values dynamic/evolving values (values "over time”), a.k.a DataFlow
Variables , e.g., temperature , vehicle speed, Stock symbol etc.
Signals/Events ‘Changing a value’ is an Event. Anything that happens multiple times
and/or that might be triggered at random intervals should be implemented as Signals/Events.
Event Streams are sources of events. Streams of timed values. These can be mouse
clicks, keyboard events, mouse drag or any other input. Streams are composable. demand-driven
(pull) sampling vs., data-driven (push) evaluation.
Functional Reactive Bindings controlled data binding.
AngularJS team reported that their code ran 20-40 times faster than it had previously switching
to Object.observe
34. typeahead search with FRP
distinct stream guaranteed that events:
1. will be non-empty strings with length
greater than two
2. will not occur too frequently, and
3. will not include duplicates.
This creates an event stream from all keyup
and change events on the given input.
The stream is transformed into a stream of
strings matching the value of the input when
each event occurs.
Then that stream is filtered so that
subscribers to inputs will only receive
events if the value of the input has a length
greater than two.
35. Promises , Generators and FRP comparison
Service
<news></news>
Model
Promise
Back End
<news></news>
Model
<news></news>
Model
Generator
Observable (FRP)
Promise.then()
• Emit result only once
Generator.next()
• Emit results until the end
• Caller driven execution
Observable.subscribe()
• Results emitted as
and when available
in sequence.
UI Component
36. Sync & Async APIs with single & multi-valued response
Single Multiple
Sync T getData() Generator<T> getData()
Async Promise<T> getData() Observable<T> getData()
synchronous scalar response Sync: multi-value iterable response, execution deferred to next() call
Async scalar response
Observable supports single value, a sequence of values or
an infinite stream and enable reactive programming model.
37. FRP is abstracted from source of
concurrency.
It is not opinionated and allows the
implementer to decide.
For example, an Observable API could just
use calling thread to synchronously
execute and respond...
or it could use a thread-pool to do the
work asynchronously and callback with
that thread....
or it could use multiple threads, each thread
calling back via onNext(T) when the value is
ready....
Your choice of concurrency implantation
38. or it could use actor pattern instead of a
thread-pool...
Do work asynchronously on an Actor (or
multiple Actors)
... or NIO with even-loop...
Do network access asynchronously using
NIO and perform callback on Event Loop.
... or thread-pool/actor that does the work but
then performs the callback via an event-loop
so the thread-pool/actor is tuned for IO and
event-loop for CPU.
All of those different implementation choices are possible
without changing the signature of the method and
without the calling code changing their behavior or how
they interact with or compose responses
39. Asynchronous Observable with Single value Synchronous Observable with Multiple value
Asynchronous Observable with Multiple value
Client: Subscribe to Asynchronous Observer
45. Web components are ...
Custom Elements
Decorators
<Template>
HTML Imports
Object.observe
Shadow DOM
Polymer, the Web Components polyfill
DOM Mutation Observers
Pointer Events
Web Animations
46. Web Components are...
The Web Components API is a collection of four different specs
from the W3C designed to work together:
• HTML Templates
– inert chunks of DOM activated when needed. <template>
• Custom Elements,
– create new HTML elements, extend existing DOM objects.
– Give them an API with properties and methods.
• Shadow DOM
– style & DOM encapsulation
• HTML Imports
– bundle and distribute common HTML/CSS/JS (e.g. components)
47. Custom Elements
1. New standards to create custom html elements.
2. Encapsulation HTML and CSS into ShadowDOM.
3. Mimic built-in elements as closely as possible. DOM
API treats custom elements as first-class
(e.g. appendChild accepts custom elements).
4. Elements can be inserted using either HTML markup
or scripts.
5. Lets designers use custom elements like HTML
6. Think of HealthCare UI Components that
complement to HBS Services. Which can be used as UI
building blocks to build HealthCare WebApps
49. Create Your Own HTML tags
<polymer-ui-accordion>
<polymer-ui-animated-pages>
<polymer-ui-overlay>
<polymer-ui-card>
<polymer-ui-sidebar-menu>
<polymer-ui-tabs>
<polymer-ui-toggle-button>
<polymer-ui-theme-aware>
52. DI vs. AMD
AngularJS inject Instances
RequireJS inject Classes
• Developers use RequireJS to asynchronously load
JavaScript and establish package/import dependencies.
• Think of AngularJS DI as injecting instances and RequireJS
AMD DI as injecting Classes or constructors
• Avoiding Scope Pollution
• ES6 Modules ~= Java Packages
• Watch out for Cyclic dependencies
• DI 2.0 : Hieratical Injectors , singleton, prototype scopes
54. SPA Navigation
• Navigating deep-links with HTML5 History API and UI Router
• UI driven back navigation for SPA
• undo , redo , work-in-progress
• 401/403: Pause for login, and show the destination page on success
55. Synchronized Cache
• Backend: Hibernate 2nd level cache
– All shared domain instances + selective queries are cached
– RESTful API bulk pagination with maxResults and offset
• Frontend: HTTP Cache
– RESTful API with Last-Modified &If-Modified-Since support
– RESTful API with Etag & If-None-Match support
• Frontend: angular-cache
– Sensible cache configuration for each cached object type,
managed at angular service level.
– ngTable module for local pagination, sort, filter
– Client can specify which fields should be included in results
60. SPA Authentication and Authorization
• Authentication - Show login Dialog
– Http Interceptor - when server return 401 (just-in-time)
– When user clicks login link in the header.
– Session Expiration - when server return 419/440
– Redirect to target view after successfully login.
• Permission based Access Control
– Restrict UI visibility - Showing or hiding part of the
screens based on the user permissions.
– Routing - When the user access a route that he
doesn’t have permission, will show error message.
– Http Interceptor - when server return 403, emit event
61. oAuth for securing backend APIs
oAuth liberate from last
mile statelessness for your
backend components
Source: http://alvarosanchez.github.io/grails-spring-security-rest/docs/index.html
62. Double oAuth: managing 3rd party issued tokens
Source: http://alvarosanchez.github.io/grails-spring-security-rest/docs/index.html
Functors, Applicatives, And Monads In Pictures - http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
Functors: you apply a function to a wrapped value using fmap or <$>
Functors are defined as a function encapsulated in an object. e.g., UnaryPredicate , Comparator
The fact that these functions are encapsulated by real objects is also the reason for its greatest benefit.
Applicatives: you apply a wrapped function to a wrapped value using <*> or liftA
Monads: you apply a function that returns a wrapped value, to a wrapped value using >>= or liftM
Java8’s Monads : Options, Maybe
Monad is the triple (T, η, μ) where
T is the Monad Functor
η is the unit function that lifts an ordinary object (a unit) into the Monad functor; and,
μ is the join function that takes a composed monad M (M a) and returns the simplified type of the composition, or M a.