SlideShare a Scribd company logo
1 of 64
Download to read offline
The Art of
Matt Raible • http://raibledesigns.com
Photos by
Modern Principles in Web Development
Design for mobile first (even if you’re
not building a mobile app)

Build only single page apps

Create and use your own REST API

“Sex sells” applies to web apps

© 2014 Raible Designs
Jobs on Dice.com
February 2014
500

375

250

125

© 2014 Raible Designs

ut
ko
oc
Kn

be
r
Em

lar
gu
An

Ba

ck

bo
n

e

0
LinkedIn Skills
February 2014
30,000

22,500

15,000

7,500

© 2014 Raible Designs

be
r
Em

ut
ko
oc
Kn

lar
gu
An

Ba

ck

bo
n

e

0
Google Trends

© 2014 Raible Designs
Indeed Job Trends

Absolute
Relative
© 2014 Raible Designs
Stack Overflow

© 2014 Raible Designs
Who wants to learn

© 2014 Raible Designs

?
The History of AngularJS
Started by Miško Hevery in 2009

GWT = 3 developers, 6 months

AngularJS = 1 developer, 3 weeks

Learn more:

https://www.youtube.com/watch?v=X0VsStcCCM8

© 2014 Raible Designs
The History of AngularJS
AngularJS

GWT

18000

17,000
13500
9000
4500
0

1,000

Lines of Code

© 2014 Raible Designs
Hello World
<!doctype html>
<html ng-app>
<head>
<title>Hello World</title>
</head>
<body>
<div>
<label>Name:</label>
<input type="text" ng-model="name" placeholder="Enter a name here">
<hr>
<h1>Hello {{name}}!</h1>
</div>
<script src="http://code.angularjs.org/1.2.13/angular.min.js"></script>
</body>
</html>

© 2014 Raible Designs
Architecture Principles

Boilerplate

Structure

D.R.Y.
Testability
© 2014 Raible Designs
Code Organization
Start with Angular Seed*

!

git clone https://github.com/angular/angular-seed.git

!
!
!

* more options to be discussed later…
© 2014 Raible Designs
App Definition
var app = angular.module('myApp', []);

<!DOCTYPE html>
<html ng-app="myApp">

© 2014 Raible Designs
App Definition with separate files
app.js

!
!

angular.module('myApp', ['ngRoute',
'myApp.filters',
'myApp.services',
'myApp.directives',
'myApp.controllers'
])

controllers.js
angular.module('myApp.controllers', []).
controller('MyCtrl1', [function() {
!
}])

© 2014 Raible Designs
Model View Controller

© 2014 Raible Designs
Data Binding
friend.js

!

$scope.friend = {
name: "Fernand"
};

!

friend.html

{{friend.name}}
// 1-way
<input ng-model="friend.name"> // 2-way

© 2014 Raible Designs
Solving FOUC
This will work just fine — if it’s not on the first page:

!

<p>{{friend.name}}</p>

Use ng-cloak or ng-bind attribute:

<p ng-cloak>{{friend.name}}</p>
!
<p ng-bind="friend.name"></p>

© 2014 Raible Designs
Directives
<div ng-repeat="entry in news.entries">
<span ng-bind="entry.title"></span>
<button ng-click="delete($index)">
Delete
</button>
</div>

© 2014 Raible Designs
Directives with valid HTML5
<div data-ng-repeat="entry in news.entries">
<span data-ng-bind="entry.title"></span>
<button data-ng-click="delete($index)">
Delete
</button>
</div>
<div data-ng:repeat="entry in news.entries">
<span data-ng:bind="entry.title"></span>
<button data-ng:click="delete($index)">
Delete
</button>
</div>

© 2014 Raible Designs
Custom Directives
$scope.customer = {
name: 'Franklin',
address: '1830 Blake'
};
<div ng-controller="MyController">
<my-customer></my-customer>
</div>

.directive('myCustomer', function() {
return {
template: 'Name: {{customer.name}} 
Address: {{customer.address}}'
};
});

© 2014 Raible Designs
Built-In Directives
ng-href


ng-selected


ng-src


ng-class


ng-disabled


ng-style


ng-checked


!

ng-readonly


© 2014 Raible Designs
Services
var services = angular.module('myApp.services', ['ngResource']);
!
services.factory('LoginService', function($resource) {
return $resource(':action', {}, {
authenticate: {
method: 'POST',
params: {'action': 'authenticate'},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}
}
);
});
!
services.factory('NewsService', function($resource) {
return $resource('news/:id', {id: '@id'});
});

© 2014 Raible Designs
$http
$http({method: 'GET', url: '/news'}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});

$http.get('/news').success(successCallback);
$http.post('/news', data).success(successCallback);

© 2014 Raible Designs
$q
myApp.factory('HelloWorld', function($q, $timeout) {
!
var getMessages = function() {
var deferred = $q.defer();
!
$timeout(function() {
deferred.resolve(['Hello', 'world!']);
}, 2000);
!
return deferred.promise;
};
!
return {
getMessages: getMessages
};
});
© 2014 Raible Designs
$q
myApp.controller('HelloCtrl', function($scope, HelloWorld) {
!
HelloWorld.getMessages().then(function(messages) {
$scope.messages = messages;
});
!
});

© 2014 Raible Designs
Dependency Injection
.controller('LoginController', function($scope, $rootScope, $location,
$http, $cookieStore, LoginService) {
$scope.login = function () {
LoginService.authenticate($.param({username: $scope.username, 

password: $scope.password}),
function (user) {
$rootScope.user = user;
$http.defaults.headers.common[xAuthTokenHeaderName] = user.token;
$cookieStore.put('user', user);
$location.path("/");
});
};
})

© 2014 Raible Designs
Filters
!
!
!
!

{{ name | uppercase }}
!
<!-- Displays: 123.46 -->
{{ 123.456789 | number:2 }}
!
<!-- In en-US locale, '$1000.00' will be shown -->
{{ 1000 | currency }}
!
<!-- all of the words with e in them ["Lerner","Likes","Eat"] -->
{{ ['Ari', 'Lerner', 'Likes', 'To', 'Eat', 'Pizza'] | filter:'e' }}

!

also: lowercase, limitTo, orderBy
© 2014 Raible Designs
Routes
.config(['$routeProvider', '$locationProvider', '$httpProvider',
function ($routeProvider, $locationProvider, $httpProvider) {
$routeProvider.when('/create', {
templateUrl: 'partials/create.html', controller: 'CreateController'
});
$routeProvider.when('/edit/:id', {
templateUrl: 'partials/edit.html', controller: 'EditController'
});
$routeProvider.when('/login', {
templateUrl: 'partials/login.html', controller: 'LoginController'
});
$routeProvider.otherwise({
templateUrl: 'partials/index.html', controller: 'IndexController'
});
!
$locationProvider.hashPrefix('!');
}]
)
© 2014 Raible Designs
Routing: Navigation
$rootScope.logout = function () {
delete $rootScope.user;
delete $http.defaults.headers.common[xAuthTokenHeaderName];
$cookieStore.remove('user');
$location.path("/login");
};

© 2014 Raible Designs
Routing: Navigation
$rootScope.logout = function () {
delete $rootScope.user;
delete $http.defaults.headers.common[xAuthTokenHeaderName];
$cookieStore.remove('user');
$location.path("/login");
};

© 2014 Raible Designs
Code Organization Revisited
Lineman helps you build fat-client JavaScript apps

It produces happiness by building assets, mocking servers, and running
specs on every file change
git clone https://github.com/linemanjs/lineman-angular-template.git my-app
cd my-app
sudo npm install -g lineman
npm install
lineman run

© 2014 Raible Designs
Google's Recommendations for Angular App Structure
Testing
Testem - test runner, framework agnostic

Jasmine - unit tests, framework agnostic

Protractor - integration tests, angular specific

Lineman - productivity, framework agnostic

© 2014 Raible Designs
Testing: Controllers
describe("controller: LoginController", function() {
!
beforeEach(function() {
module("app");
});
!
beforeEach(inject(function($controller, $rootScope, $location,
AuthenticationService, $httpBackend) {
this.$location = $location;
this.$httpBackend = $httpBackend;
this.scope = $rootScope.$new();
this.redirect = spyOn($location, 'path');
$controller('LoginController', {
$scope: this.scope,
$location: $location,
AuthenticationService: AuthenticationService
});
}));
© 2014 Raible Designs
Testing: Controllers
afterEach(function() {
this.$httpBackend.verifyNoOutstandingRequest();
this.$httpBackend.verifyNoOutstandingExpectation();
});

!

describe("successfully logging in", function() {
it("should redirect you to /home", function() {
this.$httpBackend.expectPOST('/login',
this.scope.credentials).respond(200);
this.scope.login();
this.$httpBackend.flush();
expect(this.redirect).toHaveBeenCalledWith('/home');
});
});

});

© 2014 Raible Designs
Testing: Directives
beforeEach(inject(function($rootScope, $compile) {
this.directiveMessage = 'ralph was here';
this.html = "<div shows-message-when-hovered message='"
+ this.directiveMessage + "'></div>";
this.scope = $rootScope.$new();
this.scope.message = this.originalMessage = 'things are looking grim';
this.elem = $compile(this.html)(this.scope);
}));
!
describe("when a user mouses over the element", function() {
it("sets the message on the scope to the message attribute", function() {
this.elem.triggerHandler('mouseenter');
expect(this.scope.message).toBe(this.directiveMessage);
});
});

© 2014 Raible Designs
Testing: Directives with CoffeeScript
describe "directive: shows-message-when-hovered (coffeescript)", ->
!
Given -> module("app")
!
Given inject ($rootScope, $compile) ->
@directiveMessage = 'ralph was here'
@html = "<div shows-message-when-hovered
message='#{@directiveMessage}'></div>"
@scope = $rootScope.$new()
@scope.message = @originalMessage = 'things are looking grim'
@elem = $compile(@html)(@scope)
!
describe "when a user mouses over the element", ->
When -> @elem.triggerHandler('mouseenter')
Then "the message on the scope is set to the message attribute", ->
@scope.message == @directiveMessage

© 2014 Raible Designs
Testing: End-to-End
protractor = require("protractor")
require "protractor/jasminewd"
require 'jasmine-given'

!

describe "my angular app", ->
ptor = protractor.getInstance()
describe "visiting the login page", ->
Given -> ptor.get "/"

!

describe "when a user logs in", ->
Given -> ptor.findElement(protractor.By.input("credentials.username")).sendKeys "Ralph"
Given -> ptor.findElement(protractor.By.input("credentials.password")).sendKeys "Wiggum"
When -> ptor.findElement(protractor.By.id("log-in")).click()
Then -> ptor.findElement(protractor.By.binding("{{ message }}")).getText().then (text) ->
expect(text).toEqual "Mouse Over these images to see a directive at work"

© 2014 Raible Designs
Building with Grunt
sudo npm install
!
sudo npm install -g grunt-cli
!
vi package.json
!
"grunt": "~0.4.1",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-uglify": "~0.2.7",
"grunt-contrib-cssmin": "~0.7.0",
"grunt-usemin": "~2.0.2",
"grunt-contrib-copy": "~0.5.0",
"grunt-rev": "~0.1.0",
"grunt-contrib-clean": "~0.5.0",
"matchdep": "~0.3.0"

© 2014 Raible Designs
Gruntfile.js
module.exports = function (grunt) {

!
!
!

!

grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
clean: ["dist", '.tmp'],
copy: {
main: {
expand: true,
cwd: 'app/',
src: ['**', '!js/**', '!lib/**', '!**/*.css'],
dest: 'dist/'
}
},
rev: {
files: {
src: ['dist/**/*.{js,css}']
}
},
© 2014 Raible Designs
Gruntfile.js
!

useminPrepare: {
html: 'app/index.html'
},

!

usemin: {
html: ['dist/index.html']
},

!

uglify: {
options: {
report: 'min',
mangle: false
}
}
});

!
© 2014 Raible Designs
Gruntfile.js
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

!

// Tell Grunt what to do when we type "grunt" into the terminal
grunt.registerTask('default', [
'copy', 'useminPrepare', 'concat', 'uglify', 'cssmin', 'rev', 'usemin'
]);

};

© 2014 Raible Designs
index.html comments
<head>
<title>My AngularJS App</title>
<!-- build:css css/seed.min.css -->
<link rel="stylesheet" href="css/app.css"/>
<link rel="stylesheet" href="css/app2.css"/>
<!-- endbuild -->
</head>
<body>
<!-- build:js js/seed.min.js -->
<script src="lib/angular/angular.js"></script>
<script src="lib/angular/angular-route.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/directives.js"></script>
<!-- endbuild -->
</body>
© 2014 Raible Designs
dist/index.html
<head>
<title>My AngularJS App</title>
<link rel="stylesheet" href="css/f050d0dc.seed.min.css"/>
</head>
<body>
!
<script src="js/8973cf0f.seed.min.js"></script>
</body>

© 2014 Raible Designs
After Grunt

http://raibledesigns.com/rd/entry/using_grunt_with_angularjs_for

© 2014 Raible Designs
You shouldn’t have to worry about FEO

http://raibledesigns.com/rd/entry/you_shouldn_t_have_to
© 2014 Raible Designs
HTTP/2 Performance Anti-Patterns?
Split dominant content domains

Reduce requests

	 Merging

	 Sprites

	 DataURIs
http://www.slideshare.net/andydavies
© 2014 Raible Designs
CloudBees

© 2014 Raible Designs
UI Bootstrap

http://angular-ui.github.io/bootstrap

<script src="lib/angular/ui-bootstrap-0.10.0.min.js"></script>
<script src="lib/angular/ui-bootstrap-tpls-0.10.0.min.js"></script>
angular.module('myApp', ['ui.bootstrap']);

© 2014 Raible Designs
Ionic Framework

http://ionicframework.com

© 2014 Raible Designs
AngularJS Batarang

© 2014 Raible Designs
My Experience
Developing with AngularJS Series

Part I: The Basics

Part II: Dialogs and Data

Part III: Services

Part IV: Making it Pop


© 2014 Raible Designs
My Experience

http://vimeo.com/mraible/angularjs-deep-dive

#dv13javaweb$

© 2014 Raible Designs
How to Become an Artist
Part 1 of 3: Learn the Basics on Your Own

Take some time and try various mediums of art

Recognize your strengths

Do your research and learn the basics

Get the supplies you will need

Observe the world around you

Make time for your art every day

Seek out the opinions of others

Develop your own style

http://www.wikihow.com/Become-an-Artist
© 2014 Raible Designs
Shortcut to becoming an Angular Artist

JUST DO IT.
© 2014 Raible Designs
Questions?
Contact Me!

http://raibledesigns.com

@mraible


Presentations

http://slideshare.net/mraible


Code

http://github.com/mraible
© 2014 Raible Designs
Who to follow on Twitter
AngularJS Team at Google


Web Performance


	 Miško Hevery - @mhevery


	 Ilya Grigorik - @igrigorik


	 Igor Minar - @IgorMinar


	 Andy Davis - @andydavies


	 Brian Ford - @briantford


	 Steve Souders - @Souders


!

© 2014 Raible Designs
Resources
Angular Dart

	 https://angulardart.org 

Devoxx AngularJS Talks on Parleys.com 

http://parleys.com/play/5148922b0364bc17fc56c91b (2012)

http://parleys.com/play/529321a5e4b054cd7d2ef4e1 (2013)

Egghead.io - https://egghead.io/
© 2014 Raible Designs
Code
Angular Seed

https://github.com/angular/angular-seed 

Lineman Application Template using AngularJS

	 https://github.com/linemanjs/lineman-angular-template

AngularJS + Rest + Spring Security

	 https://github.com/joshlong/boot-examples/tree/master/x-auth-security
© 2014 Raible Designs

More Related Content

What's hot

AngularJS - What is it & Why is it awesome ? (with demos)
AngularJS - What is it & Why is it awesome ? (with demos)AngularJS - What is it & Why is it awesome ? (with demos)
AngularJS - What is it & Why is it awesome ? (with demos)Gary Arora
 
Why angular js Framework
Why angular js Framework Why angular js Framework
Why angular js Framework Sakthi Bro
 
Advanced Tips & Tricks for using Angular JS
Advanced Tips & Tricks for using Angular JSAdvanced Tips & Tricks for using Angular JS
Advanced Tips & Tricks for using Angular JSSimon Guest
 
Introduction to AJAX In WordPress
Introduction to AJAX In WordPressIntroduction to AJAX In WordPress
Introduction to AJAX In WordPressCaldera Labs
 
AngularJS - The Next Big Thing?
AngularJS - The Next Big Thing?AngularJS - The Next Big Thing?
AngularJS - The Next Big Thing?Tom Hombergs
 
AngularJS Basics
AngularJS BasicsAngularJS Basics
AngularJS BasicsRavi Mone
 
Single Page WebApp Architecture
Single Page WebApp ArchitectureSingle Page WebApp Architecture
Single Page WebApp ArchitectureMorgan Cheng
 
AngularJS application architecture
AngularJS application architectureAngularJS application architecture
AngularJS application architectureGabriele Falace
 
Single Page Applications in SharePoint with Angular
Single Page Applications in SharePoint with AngularSingle Page Applications in SharePoint with Angular
Single Page Applications in SharePoint with AngularSparkhound Inc.
 
Angular js for beginners
Angular js for beginnersAngular js for beginners
Angular js for beginnersMunir Hoque
 
Angular Best Practices v2
Angular Best Practices v2Angular Best Practices v2
Angular Best Practices v2Henry Tao
 
AngularJS with RequireJS
AngularJS with RequireJSAngularJS with RequireJS
AngularJS with RequireJSJohannes Weber
 
AngularJS Basics and Best Practices - CC FE &UX
AngularJS Basics and Best Practices - CC FE &UXAngularJS Basics and Best Practices - CC FE &UX
AngularJS Basics and Best Practices - CC FE &UXJWORKS powered by Ordina
 
AngularJS intro
AngularJS introAngularJS intro
AngularJS introdizabl
 
multiple views and routing
multiple views and routingmultiple views and routing
multiple views and routingBrajesh Yadav
 

What's hot (20)

AngularJS Best Practices
AngularJS Best PracticesAngularJS Best Practices
AngularJS Best Practices
 
AngularJS - What is it & Why is it awesome ? (with demos)
AngularJS - What is it & Why is it awesome ? (with demos)AngularJS - What is it & Why is it awesome ? (with demos)
AngularJS - What is it & Why is it awesome ? (with demos)
 
Introduction to AngularJS
Introduction to AngularJSIntroduction to AngularJS
Introduction to AngularJS
 
Why angular js Framework
Why angular js Framework Why angular js Framework
Why angular js Framework
 
Advanced Tips & Tricks for using Angular JS
Advanced Tips & Tricks for using Angular JSAdvanced Tips & Tricks for using Angular JS
Advanced Tips & Tricks for using Angular JS
 
Introduction to AJAX In WordPress
Introduction to AJAX In WordPressIntroduction to AJAX In WordPress
Introduction to AJAX In WordPress
 
AngularJS - The Next Big Thing?
AngularJS - The Next Big Thing?AngularJS - The Next Big Thing?
AngularJS - The Next Big Thing?
 
AngularJS Basics
AngularJS BasicsAngularJS Basics
AngularJS Basics
 
Single Page WebApp Architecture
Single Page WebApp ArchitectureSingle Page WebApp Architecture
Single Page WebApp Architecture
 
AngularJS application architecture
AngularJS application architectureAngularJS application architecture
AngularJS application architecture
 
Single Page Applications in SharePoint with Angular
Single Page Applications in SharePoint with AngularSingle Page Applications in SharePoint with Angular
Single Page Applications in SharePoint with Angular
 
Angular js for beginners
Angular js for beginnersAngular js for beginners
Angular js for beginners
 
Angular Best Practices v2
Angular Best Practices v2Angular Best Practices v2
Angular Best Practices v2
 
AngularJS with RequireJS
AngularJS with RequireJSAngularJS with RequireJS
AngularJS with RequireJS
 
AngularJS Basics and Best Practices - CC FE &UX
AngularJS Basics and Best Practices - CC FE &UXAngularJS Basics and Best Practices - CC FE &UX
AngularJS Basics and Best Practices - CC FE &UX
 
AngularJS intro
AngularJS introAngularJS intro
AngularJS intro
 
Angular js PPT
Angular js PPTAngular js PPT
Angular js PPT
 
Angular js
Angular jsAngular js
Angular js
 
Introduction to Angularjs
Introduction to AngularjsIntroduction to Angularjs
Introduction to Angularjs
 
multiple views and routing
multiple views and routingmultiple views and routing
multiple views and routing
 

Similar to The Art of AngularJS - DeRailed 2014

AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJSAngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJSmurtazahaveliwala
 
ASP.NET MVC, AngularJS CRUD for Azerbaijan Technical University
ASP.NET MVC, AngularJS CRUD for Azerbaijan Technical UniversityASP.NET MVC, AngularJS CRUD for Azerbaijan Technical University
ASP.NET MVC, AngularJS CRUD for Azerbaijan Technical UniversitySyed Shanu
 
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Fwdays
 
I Know It Was MEAN, But I Cut the Cord to LAMP Anyway
I Know It Was MEAN, But I Cut the Cord to LAMP AnywayI Know It Was MEAN, But I Cut the Cord to LAMP Anyway
I Know It Was MEAN, But I Cut the Cord to LAMP AnywayAll Things Open
 
Ruby on Rails + AngularJS + Twitter Bootstrap
Ruby on Rails + AngularJS + Twitter BootstrapRuby on Rails + AngularJS + Twitter Bootstrap
Ruby on Rails + AngularJS + Twitter BootstrapMarcio Marinho
 
Angular data binding by Soft Solutions4U
Angular data binding by Soft Solutions4UAngular data binding by Soft Solutions4U
Angular data binding by Soft Solutions4Usharsen
 
Efektivni vyvoj webovych aplikaci v Ruby on Rails (Webexpo)
Efektivni vyvoj webovych aplikaci v Ruby on Rails (Webexpo)Efektivni vyvoj webovych aplikaci v Ruby on Rails (Webexpo)
Efektivni vyvoj webovych aplikaci v Ruby on Rails (Webexpo)Karel Minarik
 
I Know It Was MEAN, But I Cut the Cord to LAMP Anyway
I Know It Was MEAN, But I Cut the Cord to LAMP AnywayI Know It Was MEAN, But I Cut the Cord to LAMP Anyway
I Know It Was MEAN, But I Cut the Cord to LAMP AnywayPOSSCON
 
A gently introduction to AngularJS
A gently introduction to AngularJSA gently introduction to AngularJS
A gently introduction to AngularJSGregor Woiwode
 
The Modern Java Web Developer - JavaOne 2013
The Modern Java Web Developer - JavaOne 2013The Modern Java Web Developer - JavaOne 2013
The Modern Java Web Developer - JavaOne 2013Matt Raible
 
From Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) AgainFrom Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) Againjonknapp
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Eliran Eliassy
 
CFUGbe talk about Angular JS
CFUGbe talk about Angular JSCFUGbe talk about Angular JS
CFUGbe talk about Angular JSAlwyn Wymeersch
 
Node.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java sideNode.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java sideMek Srunyu Stittri
 
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 -  Fullstack end-to-end Test Automation with node.jsForwardJS 2017 -  Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.jsMek Srunyu Stittri
 

Similar to The Art of AngularJS - DeRailed 2014 (20)

AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJSAngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
 
ASP.NET MVC, AngularJS CRUD for Azerbaijan Technical University
ASP.NET MVC, AngularJS CRUD for Azerbaijan Technical UniversityASP.NET MVC, AngularJS CRUD for Azerbaijan Technical University
ASP.NET MVC, AngularJS CRUD for Azerbaijan Technical University
 
Mean stack Magics
Mean stack MagicsMean stack Magics
Mean stack Magics
 
Mini-Training: AngularJS
Mini-Training: AngularJSMini-Training: AngularJS
Mini-Training: AngularJS
 
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
 
I Know It Was MEAN, But I Cut the Cord to LAMP Anyway
I Know It Was MEAN, But I Cut the Cord to LAMP AnywayI Know It Was MEAN, But I Cut the Cord to LAMP Anyway
I Know It Was MEAN, But I Cut the Cord to LAMP Anyway
 
Ruby on Rails + AngularJS + Twitter Bootstrap
Ruby on Rails + AngularJS + Twitter BootstrapRuby on Rails + AngularJS + Twitter Bootstrap
Ruby on Rails + AngularJS + Twitter Bootstrap
 
Angular data binding by Soft Solutions4U
Angular data binding by Soft Solutions4UAngular data binding by Soft Solutions4U
Angular data binding by Soft Solutions4U
 
Efektivni vyvoj webovych aplikaci v Ruby on Rails (Webexpo)
Efektivni vyvoj webovych aplikaci v Ruby on Rails (Webexpo)Efektivni vyvoj webovych aplikaci v Ruby on Rails (Webexpo)
Efektivni vyvoj webovych aplikaci v Ruby on Rails (Webexpo)
 
I Know It Was MEAN, But I Cut the Cord to LAMP Anyway
I Know It Was MEAN, But I Cut the Cord to LAMP AnywayI Know It Was MEAN, But I Cut the Cord to LAMP Anyway
I Know It Was MEAN, But I Cut the Cord to LAMP Anyway
 
SF Cordova Meetup
SF Cordova MeetupSF Cordova Meetup
SF Cordova Meetup
 
A gently introduction to AngularJS
A gently introduction to AngularJSA gently introduction to AngularJS
A gently introduction to AngularJS
 
The Modern Java Web Developer - JavaOne 2013
The Modern Java Web Developer - JavaOne 2013The Modern Java Web Developer - JavaOne 2013
The Modern Java Web Developer - JavaOne 2013
 
Drupalcon Mumbai
Drupalcon MumbaiDrupalcon Mumbai
Drupalcon Mumbai
 
From Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) AgainFrom Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) Again
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics
 
React Native Workshop
React Native WorkshopReact Native Workshop
React Native Workshop
 
CFUGbe talk about Angular JS
CFUGbe talk about Angular JSCFUGbe talk about Angular JS
CFUGbe talk about Angular JS
 
Node.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java sideNode.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java side
 
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 -  Fullstack end-to-end Test Automation with node.jsForwardJS 2017 -  Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
 

More from Matt Raible

Keep Identities in Sync the SCIMple Way - ApacheCon NA 2022
Keep Identities in Sync the SCIMple Way - ApacheCon NA 2022Keep Identities in Sync the SCIMple Way - ApacheCon NA 2022
Keep Identities in Sync the SCIMple Way - ApacheCon NA 2022Matt Raible
 
Micro Frontends for Java Microservices - Belfast JUG 2022
Micro Frontends for Java Microservices - Belfast JUG 2022Micro Frontends for Java Microservices - Belfast JUG 2022
Micro Frontends for Java Microservices - Belfast JUG 2022Matt Raible
 
Micro Frontends for Java Microservices - Dublin JUG 2022
Micro Frontends for Java Microservices - Dublin JUG 2022Micro Frontends for Java Microservices - Dublin JUG 2022
Micro Frontends for Java Microservices - Dublin JUG 2022Matt Raible
 
Micro Frontends for Java Microservices - Cork JUG 2022
Micro Frontends for Java Microservices - Cork JUG 2022Micro Frontends for Java Microservices - Cork JUG 2022
Micro Frontends for Java Microservices - Cork JUG 2022Matt Raible
 
Comparing Native Java REST API Frameworks - Seattle JUG 2022
Comparing Native Java REST API Frameworks - Seattle JUG 2022Comparing Native Java REST API Frameworks - Seattle JUG 2022
Comparing Native Java REST API Frameworks - Seattle JUG 2022Matt Raible
 
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022Matt Raible
 
Comparing Native Java REST API Frameworks - Devoxx France 2022
Comparing Native Java REST API Frameworks - Devoxx France 2022Comparing Native Java REST API Frameworks - Devoxx France 2022
Comparing Native Java REST API Frameworks - Devoxx France 2022Matt Raible
 
Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne...
Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne...Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne...
Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne...Matt Raible
 
Native Java with Spring Boot and JHipster - Garden State JUG 2021
Native Java with Spring Boot and JHipster - Garden State JUG 2021Native Java with Spring Boot and JHipster - Garden State JUG 2021
Native Java with Spring Boot and JHipster - Garden State JUG 2021Matt Raible
 
Java REST API Framework Comparison - PWX 2021
Java REST API Framework Comparison - PWX 2021Java REST API Framework Comparison - PWX 2021
Java REST API Framework Comparison - PWX 2021Matt Raible
 
Web App Security for Java Developers - PWX 2021
Web App Security for Java Developers - PWX 2021Web App Security for Java Developers - PWX 2021
Web App Security for Java Developers - PWX 2021Matt Raible
 
Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ...
Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ...Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ...
Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ...Matt Raible
 
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker...
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker...Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker...
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker...Matt Raible
 
Web App Security for Java Developers - UberConf 2021
Web App Security for Java Developers - UberConf 2021Web App Security for Java Developers - UberConf 2021
Web App Security for Java Developers - UberConf 2021Matt Raible
 
Java REST API Framework Comparison - UberConf 2021
Java REST API Framework Comparison - UberConf 2021Java REST API Framework Comparison - UberConf 2021
Java REST API Framework Comparison - UberConf 2021Matt Raible
 
Native Java with Spring Boot and JHipster - SF JUG 2021
Native Java with Spring Boot and JHipster - SF JUG 2021Native Java with Spring Boot and JHipster - SF JUG 2021
Native Java with Spring Boot and JHipster - SF JUG 2021Matt Raible
 
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin...
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin...Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin...
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin...Matt Raible
 
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021Matt Raible
 
Get Hip with JHipster - Colorado Springs Open Source User Group 2021
Get Hip with JHipster - Colorado Springs Open Source User Group 2021Get Hip with JHipster - Colorado Springs Open Source User Group 2021
Get Hip with JHipster - Colorado Springs Open Source User Group 2021Matt Raible
 
JHipster and Okta - JHipster Virtual Meetup December 2020
JHipster and Okta - JHipster Virtual Meetup December 2020JHipster and Okta - JHipster Virtual Meetup December 2020
JHipster and Okta - JHipster Virtual Meetup December 2020Matt Raible
 

More from Matt Raible (20)

Keep Identities in Sync the SCIMple Way - ApacheCon NA 2022
Keep Identities in Sync the SCIMple Way - ApacheCon NA 2022Keep Identities in Sync the SCIMple Way - ApacheCon NA 2022
Keep Identities in Sync the SCIMple Way - ApacheCon NA 2022
 
Micro Frontends for Java Microservices - Belfast JUG 2022
Micro Frontends for Java Microservices - Belfast JUG 2022Micro Frontends for Java Microservices - Belfast JUG 2022
Micro Frontends for Java Microservices - Belfast JUG 2022
 
Micro Frontends for Java Microservices - Dublin JUG 2022
Micro Frontends for Java Microservices - Dublin JUG 2022Micro Frontends for Java Microservices - Dublin JUG 2022
Micro Frontends for Java Microservices - Dublin JUG 2022
 
Micro Frontends for Java Microservices - Cork JUG 2022
Micro Frontends for Java Microservices - Cork JUG 2022Micro Frontends for Java Microservices - Cork JUG 2022
Micro Frontends for Java Microservices - Cork JUG 2022
 
Comparing Native Java REST API Frameworks - Seattle JUG 2022
Comparing Native Java REST API Frameworks - Seattle JUG 2022Comparing Native Java REST API Frameworks - Seattle JUG 2022
Comparing Native Java REST API Frameworks - Seattle JUG 2022
 
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022
 
Comparing Native Java REST API Frameworks - Devoxx France 2022
Comparing Native Java REST API Frameworks - Devoxx France 2022Comparing Native Java REST API Frameworks - Devoxx France 2022
Comparing Native Java REST API Frameworks - Devoxx France 2022
 
Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne...
Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne...Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne...
Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne...
 
Native Java with Spring Boot and JHipster - Garden State JUG 2021
Native Java with Spring Boot and JHipster - Garden State JUG 2021Native Java with Spring Boot and JHipster - Garden State JUG 2021
Native Java with Spring Boot and JHipster - Garden State JUG 2021
 
Java REST API Framework Comparison - PWX 2021
Java REST API Framework Comparison - PWX 2021Java REST API Framework Comparison - PWX 2021
Java REST API Framework Comparison - PWX 2021
 
Web App Security for Java Developers - PWX 2021
Web App Security for Java Developers - PWX 2021Web App Security for Java Developers - PWX 2021
Web App Security for Java Developers - PWX 2021
 
Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ...
Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ...Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ...
Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ...
 
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker...
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker...Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker...
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker...
 
Web App Security for Java Developers - UberConf 2021
Web App Security for Java Developers - UberConf 2021Web App Security for Java Developers - UberConf 2021
Web App Security for Java Developers - UberConf 2021
 
Java REST API Framework Comparison - UberConf 2021
Java REST API Framework Comparison - UberConf 2021Java REST API Framework Comparison - UberConf 2021
Java REST API Framework Comparison - UberConf 2021
 
Native Java with Spring Boot and JHipster - SF JUG 2021
Native Java with Spring Boot and JHipster - SF JUG 2021Native Java with Spring Boot and JHipster - SF JUG 2021
Native Java with Spring Boot and JHipster - SF JUG 2021
 
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin...
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin...Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin...
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin...
 
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021
 
Get Hip with JHipster - Colorado Springs Open Source User Group 2021
Get Hip with JHipster - Colorado Springs Open Source User Group 2021Get Hip with JHipster - Colorado Springs Open Source User Group 2021
Get Hip with JHipster - Colorado Springs Open Source User Group 2021
 
JHipster and Okta - JHipster Virtual Meetup December 2020
JHipster and Okta - JHipster Virtual Meetup December 2020JHipster and Okta - JHipster Virtual Meetup December 2020
JHipster and Okta - JHipster Virtual Meetup December 2020
 

Recently uploaded

Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsYoss Cohen
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...itnewsafrica
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...BookNet Canada
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFMichael Gough
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...Karmanjay Verma
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Karmanjay Verma
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 

Recently uploaded (20)

Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platforms
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDF
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 

The Art of AngularJS - DeRailed 2014

  • 1. The Art of Matt Raible • http://raibledesigns.com Photos by
  • 2. Modern Principles in Web Development Design for mobile first (even if you’re not building a mobile app) Build only single page apps Create and use your own REST API “Sex sells” applies to web apps © 2014 Raible Designs
  • 3.
  • 4. Jobs on Dice.com February 2014 500 375 250 125 © 2014 Raible Designs ut ko oc Kn be r Em lar gu An Ba ck bo n e 0
  • 5. LinkedIn Skills February 2014 30,000 22,500 15,000 7,500 © 2014 Raible Designs be r Em ut ko oc Kn lar gu An Ba ck bo n e 0
  • 6. Google Trends © 2014 Raible Designs
  • 8. Stack Overflow © 2014 Raible Designs
  • 9. Who wants to learn © 2014 Raible Designs ?
  • 10. The History of AngularJS Started by Miško Hevery in 2009 GWT = 3 developers, 6 months AngularJS = 1 developer, 3 weeks Learn more: https://www.youtube.com/watch?v=X0VsStcCCM8 © 2014 Raible Designs
  • 11. The History of AngularJS AngularJS GWT 18000 17,000 13500 9000 4500 0 1,000 Lines of Code © 2014 Raible Designs
  • 12. Hello World <!doctype html> <html ng-app> <head> <title>Hello World</title> </head> <body> <div> <label>Name:</label> <input type="text" ng-model="name" placeholder="Enter a name here"> <hr> <h1>Hello {{name}}!</h1> </div> <script src="http://code.angularjs.org/1.2.13/angular.min.js"></script> </body> </html> © 2014 Raible Designs
  • 14. Code Organization Start with Angular Seed* ! git clone https://github.com/angular/angular-seed.git ! ! ! * more options to be discussed later… © 2014 Raible Designs
  • 15. App Definition var app = angular.module('myApp', []); <!DOCTYPE html> <html ng-app="myApp"> © 2014 Raible Designs
  • 16. App Definition with separate files app.js ! ! angular.module('myApp', ['ngRoute', 'myApp.filters', 'myApp.services', 'myApp.directives', 'myApp.controllers' ]) controllers.js angular.module('myApp.controllers', []). controller('MyCtrl1', [function() { ! }]) © 2014 Raible Designs
  • 17. Model View Controller © 2014 Raible Designs
  • 18. Data Binding friend.js ! $scope.friend = { name: "Fernand" }; ! friend.html {{friend.name}} // 1-way <input ng-model="friend.name"> // 2-way © 2014 Raible Designs
  • 19. Solving FOUC This will work just fine — if it’s not on the first page: ! <p>{{friend.name}}</p> Use ng-cloak or ng-bind attribute: <p ng-cloak>{{friend.name}}</p> ! <p ng-bind="friend.name"></p> © 2014 Raible Designs
  • 20. Directives <div ng-repeat="entry in news.entries"> <span ng-bind="entry.title"></span> <button ng-click="delete($index)"> Delete </button> </div> © 2014 Raible Designs
  • 21. Directives with valid HTML5 <div data-ng-repeat="entry in news.entries"> <span data-ng-bind="entry.title"></span> <button data-ng-click="delete($index)"> Delete </button> </div> <div data-ng:repeat="entry in news.entries"> <span data-ng:bind="entry.title"></span> <button data-ng:click="delete($index)"> Delete </button> </div> © 2014 Raible Designs
  • 22. Custom Directives $scope.customer = { name: 'Franklin', address: '1830 Blake' }; <div ng-controller="MyController"> <my-customer></my-customer> </div> .directive('myCustomer', function() { return { template: 'Name: {{customer.name}} Address: {{customer.address}}' }; }); © 2014 Raible Designs
  • 24. Services var services = angular.module('myApp.services', ['ngResource']); ! services.factory('LoginService', function($resource) { return $resource(':action', {}, { authenticate: { method: 'POST', params: {'action': 'authenticate'}, headers: {'Content-Type': 'application/x-www-form-urlencoded'} } } ); }); ! services.factory('NewsService', function($resource) { return $resource('news/:id', {id: '@id'}); }); © 2014 Raible Designs
  • 25. $http $http({method: 'GET', url: '/news'}). success(function(data, status, headers, config) { // this callback will be called asynchronously // when the response is available }). error(function(data, status, headers, config) { // called asynchronously if an error occurs // or server returns response with an error status. }); $http.get('/news').success(successCallback); $http.post('/news', data).success(successCallback); © 2014 Raible Designs
  • 26. $q myApp.factory('HelloWorld', function($q, $timeout) { ! var getMessages = function() { var deferred = $q.defer(); ! $timeout(function() { deferred.resolve(['Hello', 'world!']); }, 2000); ! return deferred.promise; }; ! return { getMessages: getMessages }; }); © 2014 Raible Designs
  • 27. $q myApp.controller('HelloCtrl', function($scope, HelloWorld) { ! HelloWorld.getMessages().then(function(messages) { $scope.messages = messages; }); ! }); © 2014 Raible Designs
  • 28. Dependency Injection .controller('LoginController', function($scope, $rootScope, $location, $http, $cookieStore, LoginService) { $scope.login = function () { LoginService.authenticate($.param({username: $scope.username, 
 password: $scope.password}), function (user) { $rootScope.user = user; $http.defaults.headers.common[xAuthTokenHeaderName] = user.token; $cookieStore.put('user', user); $location.path("/"); }); }; }) © 2014 Raible Designs
  • 29. Filters ! ! ! ! {{ name | uppercase }} ! <!-- Displays: 123.46 --> {{ 123.456789 | number:2 }} ! <!-- In en-US locale, '$1000.00' will be shown --> {{ 1000 | currency }} ! <!-- all of the words with e in them ["Lerner","Likes","Eat"] --> {{ ['Ari', 'Lerner', 'Likes', 'To', 'Eat', 'Pizza'] | filter:'e' }} ! also: lowercase, limitTo, orderBy © 2014 Raible Designs
  • 30. Routes .config(['$routeProvider', '$locationProvider', '$httpProvider', function ($routeProvider, $locationProvider, $httpProvider) { $routeProvider.when('/create', { templateUrl: 'partials/create.html', controller: 'CreateController' }); $routeProvider.when('/edit/:id', { templateUrl: 'partials/edit.html', controller: 'EditController' }); $routeProvider.when('/login', { templateUrl: 'partials/login.html', controller: 'LoginController' }); $routeProvider.otherwise({ templateUrl: 'partials/index.html', controller: 'IndexController' }); ! $locationProvider.hashPrefix('!'); }] ) © 2014 Raible Designs
  • 31. Routing: Navigation $rootScope.logout = function () { delete $rootScope.user; delete $http.defaults.headers.common[xAuthTokenHeaderName]; $cookieStore.remove('user'); $location.path("/login"); }; © 2014 Raible Designs
  • 32. Routing: Navigation $rootScope.logout = function () { delete $rootScope.user; delete $http.defaults.headers.common[xAuthTokenHeaderName]; $cookieStore.remove('user'); $location.path("/login"); }; © 2014 Raible Designs
  • 33. Code Organization Revisited Lineman helps you build fat-client JavaScript apps It produces happiness by building assets, mocking servers, and running specs on every file change git clone https://github.com/linemanjs/lineman-angular-template.git my-app cd my-app sudo npm install -g lineman npm install lineman run © 2014 Raible Designs
  • 34.
  • 35.
  • 36. Google's Recommendations for Angular App Structure
  • 37.
  • 38. Testing Testem - test runner, framework agnostic Jasmine - unit tests, framework agnostic Protractor - integration tests, angular specific Lineman - productivity, framework agnostic © 2014 Raible Designs
  • 39. Testing: Controllers describe("controller: LoginController", function() { ! beforeEach(function() { module("app"); }); ! beforeEach(inject(function($controller, $rootScope, $location, AuthenticationService, $httpBackend) { this.$location = $location; this.$httpBackend = $httpBackend; this.scope = $rootScope.$new(); this.redirect = spyOn($location, 'path'); $controller('LoginController', { $scope: this.scope, $location: $location, AuthenticationService: AuthenticationService }); })); © 2014 Raible Designs
  • 40. Testing: Controllers afterEach(function() { this.$httpBackend.verifyNoOutstandingRequest(); this.$httpBackend.verifyNoOutstandingExpectation(); }); ! describe("successfully logging in", function() { it("should redirect you to /home", function() { this.$httpBackend.expectPOST('/login', this.scope.credentials).respond(200); this.scope.login(); this.$httpBackend.flush(); expect(this.redirect).toHaveBeenCalledWith('/home'); }); }); }); © 2014 Raible Designs
  • 41. Testing: Directives beforeEach(inject(function($rootScope, $compile) { this.directiveMessage = 'ralph was here'; this.html = "<div shows-message-when-hovered message='" + this.directiveMessage + "'></div>"; this.scope = $rootScope.$new(); this.scope.message = this.originalMessage = 'things are looking grim'; this.elem = $compile(this.html)(this.scope); })); ! describe("when a user mouses over the element", function() { it("sets the message on the scope to the message attribute", function() { this.elem.triggerHandler('mouseenter'); expect(this.scope.message).toBe(this.directiveMessage); }); }); © 2014 Raible Designs
  • 42. Testing: Directives with CoffeeScript describe "directive: shows-message-when-hovered (coffeescript)", -> ! Given -> module("app") ! Given inject ($rootScope, $compile) -> @directiveMessage = 'ralph was here' @html = "<div shows-message-when-hovered message='#{@directiveMessage}'></div>" @scope = $rootScope.$new() @scope.message = @originalMessage = 'things are looking grim' @elem = $compile(@html)(@scope) ! describe "when a user mouses over the element", -> When -> @elem.triggerHandler('mouseenter') Then "the message on the scope is set to the message attribute", -> @scope.message == @directiveMessage © 2014 Raible Designs
  • 43. Testing: End-to-End protractor = require("protractor") require "protractor/jasminewd" require 'jasmine-given' ! describe "my angular app", -> ptor = protractor.getInstance() describe "visiting the login page", -> Given -> ptor.get "/" ! describe "when a user logs in", -> Given -> ptor.findElement(protractor.By.input("credentials.username")).sendKeys "Ralph" Given -> ptor.findElement(protractor.By.input("credentials.password")).sendKeys "Wiggum" When -> ptor.findElement(protractor.By.id("log-in")).click() Then -> ptor.findElement(protractor.By.binding("{{ message }}")).getText().then (text) -> expect(text).toEqual "Mouse Over these images to see a directive at work" © 2014 Raible Designs
  • 44. Building with Grunt sudo npm install ! sudo npm install -g grunt-cli ! vi package.json ! "grunt": "~0.4.1", "grunt-contrib-concat": "~0.3.0", "grunt-contrib-uglify": "~0.2.7", "grunt-contrib-cssmin": "~0.7.0", "grunt-usemin": "~2.0.2", "grunt-contrib-copy": "~0.5.0", "grunt-rev": "~0.1.0", "grunt-contrib-clean": "~0.5.0", "matchdep": "~0.3.0" © 2014 Raible Designs
  • 45. Gruntfile.js module.exports = function (grunt) { ! ! ! ! grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), clean: ["dist", '.tmp'], copy: { main: { expand: true, cwd: 'app/', src: ['**', '!js/**', '!lib/**', '!**/*.css'], dest: 'dist/' } }, rev: { files: { src: ['dist/**/*.{js,css}'] } }, © 2014 Raible Designs
  • 46. Gruntfile.js ! useminPrepare: { html: 'app/index.html' }, ! usemin: { html: ['dist/index.html'] }, ! uglify: { options: { report: 'min', mangle: false } } }); ! © 2014 Raible Designs
  • 47. Gruntfile.js require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks); ! // Tell Grunt what to do when we type "grunt" into the terminal grunt.registerTask('default', [ 'copy', 'useminPrepare', 'concat', 'uglify', 'cssmin', 'rev', 'usemin' ]); }; © 2014 Raible Designs
  • 48. index.html comments <head> <title>My AngularJS App</title> <!-- build:css css/seed.min.css --> <link rel="stylesheet" href="css/app.css"/> <link rel="stylesheet" href="css/app2.css"/> <!-- endbuild --> </head> <body> <!-- build:js js/seed.min.js --> <script src="lib/angular/angular.js"></script> <script src="lib/angular/angular-route.js"></script> <script src="js/app.js"></script> <script src="js/services.js"></script> <script src="js/controllers.js"></script> <script src="js/filters.js"></script> <script src="js/directives.js"></script> <!-- endbuild --> </body> © 2014 Raible Designs
  • 49. dist/index.html <head> <title>My AngularJS App</title> <link rel="stylesheet" href="css/f050d0dc.seed.min.css"/> </head> <body> ! <script src="js/8973cf0f.seed.min.js"></script> </body> © 2014 Raible Designs
  • 51. You shouldn’t have to worry about FEO http://raibledesigns.com/rd/entry/you_shouldn_t_have_to © 2014 Raible Designs
  • 52. HTTP/2 Performance Anti-Patterns? Split dominant content domains Reduce requests Merging Sprites DataURIs http://www.slideshare.net/andydavies © 2014 Raible Designs
  • 54. UI Bootstrap http://angular-ui.github.io/bootstrap <script src="lib/angular/ui-bootstrap-0.10.0.min.js"></script> <script src="lib/angular/ui-bootstrap-tpls-0.10.0.min.js"></script> angular.module('myApp', ['ui.bootstrap']); © 2014 Raible Designs
  • 56. AngularJS Batarang © 2014 Raible Designs
  • 57. My Experience Developing with AngularJS Series Part I: The Basics
 Part II: Dialogs and Data
 Part III: Services
 Part IV: Making it Pop
 © 2014 Raible Designs
  • 59. How to Become an Artist Part 1 of 3: Learn the Basics on Your Own Take some time and try various mediums of art Recognize your strengths Do your research and learn the basics Get the supplies you will need Observe the world around you Make time for your art every day Seek out the opinions of others Develop your own style http://www.wikihow.com/Become-an-Artist © 2014 Raible Designs
  • 60. Shortcut to becoming an Angular Artist JUST DO IT. © 2014 Raible Designs
  • 62. Who to follow on Twitter AngularJS Team at Google Web Performance Miško Hevery - @mhevery Ilya Grigorik - @igrigorik Igor Minar - @IgorMinar Andy Davis - @andydavies Brian Ford - @briantford Steve Souders - @Souders ! © 2014 Raible Designs
  • 63. Resources Angular Dart https://angulardart.org Devoxx AngularJS Talks on Parleys.com http://parleys.com/play/5148922b0364bc17fc56c91b (2012) http://parleys.com/play/529321a5e4b054cd7d2ef4e1 (2013) Egghead.io - https://egghead.io/ © 2014 Raible Designs
  • 64. Code Angular Seed https://github.com/angular/angular-seed Lineman Application Template using AngularJS https://github.com/linemanjs/lineman-angular-template AngularJS + Rest + Spring Security https://github.com/joshlong/boot-examples/tree/master/x-auth-security © 2014 Raible Designs