The Art of AngularJS in 2015

Matt Raible
Matt RaibleWeb Developer, Java Champion, and Developer Advocate at Okta
Photos by

The Art of in 2015
Matt Raible • http://raibledesigns.com
© 2014 Raible Designs
Blogger on raibledesigns.com
Founder of AppFuse
Father, Skier, Mountain
Biker, Whitewater Rafter
Web Framework Connoisseur
Who is Matt Raible?
Bus Lover
© 2015 Raible Designs
Devoxx4Kids Denver
• Teaching Kids to Program

• Java, Minecraft, robots, oh my!

• Non profit, looking for donations and
speakers

http://www.meetup.com/Devoxx4Kids-Denver/
© 2015 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
© 2015 Raible Designs
Jobs on Dice.com
January 2015
0
225
450
675
900
Backbone
Angular
Em
ber
Knockout
React
© 2015 Raible Designs
LinkedIn Skills
January 2015
0
25,000
50,000
75,000
100,000
Backbone
Angular
Knockout
Em
ber
React
© 2015 Raible Designs
Google Trends
© 2015 Raible Designs
Indeed Job Trends
Absolute
Relative
© 2015 Raible Designs
Stack Overflow
The Art of AngularJS in 2015
© 2015 Raible Designs
Who wants to learn ?
© 2015 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
© 2015 Raible Designs
The History of AngularJS
0
4500
9000
13500
18000
Lines of Code
17,000
1,000
AngularJS GWT
© 2015 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.3.11/angular.min.js"></script>
</body>
</html>
© 2015 Raible Designs
Architecture Principles
Structure
Testability
Boilerplate
D.R.Y.
© 2015 Raible Designs
Code Organization
Start with Angular Seed*

* more options to be discussed later…
git clone https://github.com/angular/angular-seed.git
© 2015 Raible Designs
Quick Demo
© 2015 Raible Designs
App Definition
var app = angular.module('myApp', []);
<!DOCTYPE html>
<html ng-app="myApp">
© 2015 Raible Designs
App Definition with separate files
app.js

controllers.js
angular.module('myApp', ['ngRoute',
'myApp.filters',
'myApp.services',
'myApp.directives',
'myApp.controllers'
])
angular.module('myApp.controllers', []).
controller('MyCtrl1', [function() {
}])
© 2015 Raible Designs
Model View Controller
© 2015 Raible Designs
Data Binding
friend.js

friend.html

$scope.friend = {
name: "Fernand"
};
{{friend.name}} // 1-way
<input ng-model="friend.name"> // 2-way
© 2015 Raible Designs
Solving FOUC
This will work just fine — if it’s not on the first page:

Use ng-cloak or ng-bind attribute:

<p>{{friend.name}}</p>
<p ng-cloak>{{friend.name}}</p>
<p ng-bind="friend.name"></p>
© 2015 Raible Designs
Directives
<div ng-repeat="entry in news.entries">
<span ng-bind="entry.title"></span>
<button ng-click="delete($index)">
Delete
</button>
</div>
© 2015 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>
© 2015 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}}'
};
});
© 2015 Raible Designs
Built-In Directives
ng-href

ng-src

ng-disabled

ng-checked

ng-readonly

ng-selected

ng-class

ng-style
© 2015 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'});
});
© 2015 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);
© 2015 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
};
});
© 2015 Raible Designs
$q
myApp.controller('HelloCtrl', function($scope, HelloWorld) {
HelloWorld.getMessages().then(function(messages) {
$scope.messages = messages;
});
});
© 2015 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("/");
});
};
})
© 2015 Raible Designs
Filters
also: lowercase, limitTo, orderBy
{{ 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' }}
© 2015 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('!');
}]
)
© 2015 Raible Designs
Routing: Navigation
$rootScope.logout = function () {
delete $rootScope.user;
delete $http.defaults.headers.common[xAuthTokenHeaderName];
$cookieStore.remove('user');
$location.path("/login");
};
© 2015 Raible Designs
Routing: Navigation
$rootScope.logout = function () {
delete $rootScope.user;
delete $http.defaults.headers.common[xAuthTokenHeaderName];
$cookieStore.remove('user');
$location.path("/login");
};
© 2015 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
The Art of AngularJS in 2015
The Art of AngularJS in 2015
Google's Recommendations for Angular App Structure
The Art of AngularJS in 2015
© 2015 Raible Designs
Testing
Karma - test runner, framework agnostic

Jasmine - unit tests, framework agnostic

Protractor - integration tests, angular specific

Lineman - productivity, framework agnostic
© 2015 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
});
}));
© 2015 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');
});
});
});
© 2015 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);
});
});
© 2015 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
© 2015 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"
© 2015 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"
© 2015 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}']
}
},
© 2015 Raible Designs
Gruntfile.js
useminPrepare: {
html: 'app/index.html'
},
usemin: {
html: ['dist/index.html']
},
uglify: {
options: {
report: 'min',
mangle: false
}
}
});
© 2015 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'
]);
};
© 2015 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>
© 2015 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>
© 2015 Raible Designs
After Grunt
http://raibledesigns.com/rd/entry/using_grunt_with_angularjs_for
© 2015 Raible Designs
You shouldn’t have to worry about FEO
http://raibledesigns.com/rd/entry/you_shouldn_t_have_to
© 2015 Raible Designs
HTTP/2 Performance Anti-Patterns?
Split dominant content domains

Reduce requests

	 Merging

	 Sprites

	 DataURIs
http://www.slideshare.net/andydavies
© 2015 Raible Designs
UI Bootstrap http://angular-ui.github.io/bootstrap
<script src="lib/angular/ui-bootstrap-0.12.0.min.js"></script>
<script src="lib/angular/ui-bootstrap-tpls-0.12.0.min.js"></script>
angular.module('myApp', ['ui.bootstrap']);
© 2015 Raible Designs
UI Bootstrap: Carousel
© 2015 Raible Designs
UI Bootstrap: Carousel
<div ng-controller="CarouselDemoCtrl">
<div style="height: 305px">
<carousel interval="myInterval">
<slide ng-repeat="slide in slides" active="slide.active">
<img ng-src="{{slide.image}}" style="margin:auto;">
<div class="carousel-caption">
<h4>Slide {{$index}}</h4>
<p>{{slide.text}}</p>
</div>
</slide>
</carousel>
</div>
</div>
© 2015 Raible Designs
Foundation for Apps http://foundation.zurb.com/apps
© 2015 Raible Designs
Foundation
© 2015 Raible Designs
Foundation
© 2015 Raible Designs
Sass Mixins
<div class="row">
<main class="medium-9 columns">
<p>Main content</p>
</main>
<aside class="medium-3 columns">
<p>Sidebar</p>
</aside>
</div>
© 2015 Raible Designs
Sass Mixins
<div class="layout">
<main class="layout-content">
<p>Main content</p>
</main>
<aside class="layout-sidebar">
<p>Sidebar</p>
</aside>
</div>
© 2015 Raible Designs
Sass Mixins
http://bit.ly/1Kh1ha5
@import "foundation/components/grid";
.layout {
// `layout` container functions as a row
@include grid-row();
}
.layout-content {
// Mobile-first: make `layout-container` full-width
@include grid-column(12);
// On medium-up size, make `layout-container` 9 columns wide
@media #{$medium-up} {
@include grid-column(9);
}
}
.layout-sidebar {
// Mobile-first: make `layout-sidebar` full-width
@include grid-column(12);
// On medium-up size, make `layout-sidebar` 3 columns wide
@media #{$medium-up} {
@include grid-column(3);
}
}
© 2015 Raible Designs
Ionic Framework http://ionicframework.com
© 2015 Raible Designs#dv13javaweb$
My Ionic Experience
http://raibledesigns.com/rd/entry/developing_an_ios_native_app
© 2015 Raible Designs
JHipster http://jhipster.github.io/
© 2015 Raible Designs
JHipster
Spring Boot

Spring Security

AngularJS

Bootstrap

Bower

Metrics

Java 7 or Java 8

Maven or Gradle

Authentication Type: cookie-based or
OAuth2

Type of Database: SQL or NoSQL

Caching: EhCache or Hazelcast

Grunt or Gulp.js
http://jhipster.github.io/
Foundational Frameworks Project Options
© 2015 Raible Designs
JHipster
© 2015 Raible Designs
JHipster: Metrics
© 2015 Raible Designs
JHipster: Code Generation
© 2015 Raible Designs
JHipster: Code Generation
© 2015 Raible Designs
AngularJS Batarang
© 2015 Raible Designs
My Experience in 2013
Developing with AngularJS Series

Part I: The Basics

Part II: Dialogs and Data

Part III: Services

Part IV: Making it Pop

© 2015 Raible Designs#dv13javaweb$
My Experience in 2013
http://vimeo.com/mraible/angularjs-deep-dive
© 2015 Raible Designs
2015 AngularJS Tutorials
Getting Started with AngularJS

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

Testing AngularJS Applications

http://raibledesigns.com/rd/entry/testing_angularjs_applications
© 2015 Raible Designs
Spring and AngularJS http://spring.io/blog
http://spring.io/blog/2015/01/12/spring-and-angular-js-a-secure-single-page-application
© 2015 Raible Designs
Angular 2.0
<input type="text" [value]="firstName">
<button (click)="addPerson()">Add</button>
<input type="checkbox" [checked]="someProperty">
© 2015 Raible Designs
Concepts Eliminated in 2.0
Controllers

Directive Definition Object

$scope

angular.module

jqLite
© 2015 Raible Designs
The Bad News
No migration path from Angular 1.x to 2.0

Angular 1.3 will be supported for 1.5 - 2 years

Will only support Evergreen Browsers (e.g. IE10+)

Learn more on

http://www.infoq.com/news/2014/10/angular-2-atscript
http://12factor.net/
© 2015 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
© 2015 Raible Designs
Shortcut to becoming an Angular Artist
JUST DO IT.
© 2015 Raible Designs
Contact Me!

http://raibledesigns.com

@mraible

Presentations

http://slideshare.net/mraible

Code

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

	 Miško Hevery - @mhevery

	 Igor Minar - @IgorMinar

	 Brian Ford - @briantford

Web Performance

	 Ilya Grigorik - @igrigorik

	 Andy Davis - @andydavies

	 Steve Souders - @Souders
© 2015 Raible Designs
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/
Resources
© 2015 Raible Designs
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
Code
1 of 87

Recommended

The Art of AngularJS in 2015 - Angular Summit 2015 by
The Art of AngularJS in 2015 - Angular Summit 2015The Art of AngularJS in 2015 - Angular Summit 2015
The Art of AngularJS in 2015 - Angular Summit 2015Matt Raible
37.3K views85 slides
Get Hip with JHipster - Denver JUG 2015 by
Get Hip with JHipster - Denver JUG 2015Get Hip with JHipster - Denver JUG 2015
Get Hip with JHipster - Denver JUG 2015Matt Raible
26.6K views35 slides
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Rich Web Experie... by
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Rich Web Experie...Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Rich Web Experie...
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Rich Web Experie...Matt Raible
3.4K views41 slides
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx France 2016 by
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx France 2016Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx France 2016
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx France 2016Matt Raible
5.5K views39 slides
Thinking in Components by
Thinking in ComponentsThinking in Components
Thinking in ComponentsFITC
540 views56 slides
The Modern Java Web Developer - JavaOne 2013 by
The Modern Java Web Developer - JavaOne 2013The Modern Java Web Developer - JavaOne 2013
The Modern Java Web Developer - JavaOne 2013Matt Raible
39K views81 slides

More Related Content

What's hot

Real World Web components by
Real World Web componentsReal World Web components
Real World Web componentsJarrod Overson
8.4K views59 slides
The Art of Angular in 2016 - Devoxx UK 2016 by
The Art of Angular in 2016 - Devoxx UK 2016The Art of Angular in 2016 - Devoxx UK 2016
The Art of Angular in 2016 - Devoxx UK 2016Matt Raible
2.9K views50 slides
Gettings started with the superheroic JavaScript library AngularJS by
Gettings started with the superheroic JavaScript library AngularJSGettings started with the superheroic JavaScript library AngularJS
Gettings started with the superheroic JavaScript library AngularJSArmin Vieweg
11K views77 slides
Testing Angular 2 Applications - HTML5 Denver 2016 by
Testing Angular 2 Applications - HTML5 Denver 2016Testing Angular 2 Applications - HTML5 Denver 2016
Testing Angular 2 Applications - HTML5 Denver 2016Matt Raible
1.3K views27 slides
Web Components v1 by
Web Components v1Web Components v1
Web Components v1Mike Wilcox
778 views45 slides
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016 by
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016Matt Raible
3.7K views38 slides

What's hot(20)

Real World Web components by Jarrod Overson
Real World Web componentsReal World Web components
Real World Web components
Jarrod Overson8.4K views
The Art of Angular in 2016 - Devoxx UK 2016 by Matt Raible
The Art of Angular in 2016 - Devoxx UK 2016The Art of Angular in 2016 - Devoxx UK 2016
The Art of Angular in 2016 - Devoxx UK 2016
Matt Raible2.9K views
Gettings started with the superheroic JavaScript library AngularJS by Armin Vieweg
Gettings started with the superheroic JavaScript library AngularJSGettings started with the superheroic JavaScript library AngularJS
Gettings started with the superheroic JavaScript library AngularJS
Armin Vieweg11K views
Testing Angular 2 Applications - HTML5 Denver 2016 by Matt Raible
Testing Angular 2 Applications - HTML5 Denver 2016Testing Angular 2 Applications - HTML5 Denver 2016
Testing Angular 2 Applications - HTML5 Denver 2016
Matt Raible1.3K views
Web Components v1 by Mike Wilcox
Web Components v1Web Components v1
Web Components v1
Mike Wilcox778 views
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016 by Matt Raible
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016
Matt Raible3.7K views
Getting Started with Angular - Stormpath Webinar, January 2017 by Matt Raible
Getting Started with Angular - Stormpath Webinar, January 2017Getting Started with Angular - Stormpath Webinar, January 2017
Getting Started with Angular - Stormpath Webinar, January 2017
Matt Raible718 views
Great Responsive-ability Web Design by Mike Wilcox
Great Responsive-ability Web DesignGreat Responsive-ability Web Design
Great Responsive-ability Web Design
Mike Wilcox697 views
What's New in Spring 3.1 by Matt Raible
What's New in Spring 3.1What's New in Spring 3.1
What's New in Spring 3.1
Matt Raible7.4K views
Accessibility - A feature you can build by Monika Piotrowicz
Accessibility - A feature you can buildAccessibility - A feature you can build
Accessibility - A feature you can build
Monika Piotrowicz7.1K views
Web Frameworks of the Future: Flex, GWT, Grails and Rails by Matt Raible
Web Frameworks of the Future: Flex, GWT, Grails and RailsWeb Frameworks of the Future: Flex, GWT, Grails and Rails
Web Frameworks of the Future: Flex, GWT, Grails and Rails
Matt Raible6.8K views
Get Hip with JHipster - Colorado Springs OSS Meetup April 2016 by Matt Raible
Get Hip with JHipster - Colorado Springs OSS Meetup April 2016Get Hip with JHipster - Colorado Springs OSS Meetup April 2016
Get Hip with JHipster - Colorado Springs OSS Meetup April 2016
Matt Raible2K views
The Art of AngularJS - DeRailed 2014 by Matt Raible
The Art of AngularJS - DeRailed 2014The Art of AngularJS - DeRailed 2014
The Art of AngularJS - DeRailed 2014
Matt Raible146.5K views
Real World Web Standards by gleddy
Real World Web StandardsReal World Web Standards
Real World Web Standards
gleddy18K views
Java Web Application Security - Denver JUG 2013 by Matt Raible
Java Web Application Security - Denver JUG 2013Java Web Application Security - Denver JUG 2013
Java Web Application Security - Denver JUG 2013
Matt Raible23.8K views
The Complementarity of React and Web Components by Andrew Rota
The Complementarity of React and Web ComponentsThe Complementarity of React and Web Components
The Complementarity of React and Web Components
Andrew Rota32.3K views
Chrome enchanted 2015 by Chang W. Doh
Chrome enchanted 2015Chrome enchanted 2015
Chrome enchanted 2015
Chang W. Doh2.1K views
Building Progressive Web Apps for Android and iOS by FITC
Building Progressive Web Apps for Android and iOSBuilding Progressive Web Apps for Android and iOS
Building Progressive Web Apps for Android and iOS
FITC1.4K views
Building Mobile Applications with Ionic by Morris Singer
Building Mobile Applications with IonicBuilding Mobile Applications with Ionic
Building Mobile Applications with Ionic
Morris Singer15.1K views

Viewers also liked

CSS3 Media Queries by
CSS3 Media QueriesCSS3 Media Queries
CSS3 Media QueriesRuss Weakley
22.5K views91 slides
Beyond Media Queries: Anatomy of an Adaptive Web Design by
Beyond Media Queries: Anatomy of an Adaptive Web DesignBeyond Media Queries: Anatomy of an Adaptive Web Design
Beyond Media Queries: Anatomy of an Adaptive Web DesignBrad Frost
18.8K views133 slides
Media queries and frameworks by
Media queries and frameworksMedia queries and frameworks
Media queries and frameworksNicole Ryan
2.8K views22 slides
AngularJS best practices by
AngularJS best practicesAngularJS best practices
AngularJS best practicesFilip Bruun Bech-Larsen
713 views45 slides
AngularJS Best Practices by
AngularJS Best PracticesAngularJS Best Practices
AngularJS Best PracticesBetclic Everest Group Tech Team
25.8K views80 slides
AngularJS best-practices by
AngularJS best-practicesAngularJS best-practices
AngularJS best-practicesHenry Tao
11.8K views13 slides

Viewers also liked(11)

CSS3 Media Queries by Russ Weakley
CSS3 Media QueriesCSS3 Media Queries
CSS3 Media Queries
Russ Weakley22.5K views
Beyond Media Queries: Anatomy of an Adaptive Web Design by Brad Frost
Beyond Media Queries: Anatomy of an Adaptive Web DesignBeyond Media Queries: Anatomy of an Adaptive Web Design
Beyond Media Queries: Anatomy of an Adaptive Web Design
Brad Frost18.8K views
Media queries and frameworks by Nicole Ryan
Media queries and frameworksMedia queries and frameworks
Media queries and frameworks
Nicole Ryan2.8K views
AngularJS best-practices by Henry Tao
AngularJS best-practicesAngularJS best-practices
AngularJS best-practices
Henry Tao11.8K views
Mobile Email Design, Strategies, Workflow and Best Practices by Litmus
Mobile Email Design, Strategies, Workflow and Best PracticesMobile Email Design, Strategies, Workflow and Best Practices
Mobile Email Design, Strategies, Workflow and Best Practices
Litmus6.1K views
CSS Best practice by Russ Weakley
CSS Best practiceCSS Best practice
CSS Best practice
Russ Weakley7.2K views
New Features in Angular 1.5 by Kenichi Kanai
New Features in Angular 1.5New Features in Angular 1.5
New Features in Angular 1.5
Kenichi Kanai3K views
Css best practices style guide and tips by Chris Love
Css best practices style guide and tipsCss best practices style guide and tips
Css best practices style guide and tips
Chris Love1.5K views

Similar to The Art of AngularJS in 2015

Utilizing jQuery in SharePoint: Get More Done Faster by
Utilizing jQuery in SharePoint: Get More Done FasterUtilizing jQuery in SharePoint: Get More Done Faster
Utilizing jQuery in SharePoint: Get More Done FasterMark Rackley
472 views36 slides
The Art of Angular in 2016 - Devoxx France 2016 by
The Art of Angular in 2016 - Devoxx France 2016The Art of Angular in 2016 - Devoxx France 2016
The Art of Angular in 2016 - Devoxx France 2016Matt Raible
5.9K views50 slides
Going web native by
Going web nativeGoing web native
Going web nativeMarcus Hellberg
392 views194 slides
The Modern Java Web Developer - Denver JUG 2013 by
The Modern Java Web Developer - Denver JUG 2013The Modern Java Web Developer - Denver JUG 2013
The Modern Java Web Developer - Denver JUG 2013Matt Raible
160.7K views80 slides
Adobe & HTML5 by
Adobe & HTML5Adobe & HTML5
Adobe & HTML5Terry Ryan
1.1K views65 slides
WordPress Accessibility: WordCamp Chicago by
WordPress Accessibility: WordCamp ChicagoWordPress Accessibility: WordCamp Chicago
WordPress Accessibility: WordCamp ChicagoJoseph Dolson
9.7K views51 slides

Similar to The Art of AngularJS in 2015(20)

Utilizing jQuery in SharePoint: Get More Done Faster by Mark Rackley
Utilizing jQuery in SharePoint: Get More Done FasterUtilizing jQuery in SharePoint: Get More Done Faster
Utilizing jQuery in SharePoint: Get More Done Faster
Mark Rackley472 views
The Art of Angular in 2016 - Devoxx France 2016 by Matt Raible
The Art of Angular in 2016 - Devoxx France 2016The Art of Angular in 2016 - Devoxx France 2016
The Art of Angular in 2016 - Devoxx France 2016
Matt Raible5.9K views
The Modern Java Web Developer - Denver JUG 2013 by Matt Raible
The Modern Java Web Developer - Denver JUG 2013The Modern Java Web Developer - Denver JUG 2013
The Modern Java Web Developer - Denver JUG 2013
Matt Raible160.7K views
Adobe & HTML5 by Terry Ryan
Adobe & HTML5Adobe & HTML5
Adobe & HTML5
Terry Ryan1.1K views
WordPress Accessibility: WordCamp Chicago by Joseph Dolson
WordPress Accessibility: WordCamp ChicagoWordPress Accessibility: WordCamp Chicago
WordPress Accessibility: WordCamp Chicago
Joseph Dolson9.7K views
New Perspectives on Performance by mennovanslooten
New Perspectives on PerformanceNew Perspectives on Performance
New Perspectives on Performance
mennovanslooten4.9K views
Front End Development for Back End Developers - Denver Startup Week 2017 by Matt Raible
Front End Development for Back End Developers - Denver Startup Week 2017Front End Development for Back End Developers - Denver Startup Week 2017
Front End Development for Back End Developers - Denver Startup Week 2017
Matt Raible315 views
The Art of Angular in 2016 - vJUG24 by Matt Raible
The Art of Angular in 2016 - vJUG24The Art of Angular in 2016 - vJUG24
The Art of Angular in 2016 - vJUG24
Matt Raible1.2K views
How You Convince Your Manager To Adopt Scala.js in Production by BoldRadius Solutions
How You Convince Your Manager To Adopt Scala.js in ProductionHow You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in Production
Tulsa TechFest 2015 Awesomely Simple SharePoint Solutions by April Dunnam
Tulsa TechFest 2015 Awesomely Simple SharePoint SolutionsTulsa TechFest 2015 Awesomely Simple SharePoint Solutions
Tulsa TechFest 2015 Awesomely Simple SharePoint Solutions
April Dunnam588 views
Headless Drupal by drubb
Headless DrupalHeadless Drupal
Headless Drupal
drubb1.8K views
Vaadin Flow - JavaLand 2018 by Peter Lehto
Vaadin Flow - JavaLand 2018Vaadin Flow - JavaLand 2018
Vaadin Flow - JavaLand 2018
Peter Lehto1.5K views
RWD in the Wild by Rich Quick
RWD in the WildRWD in the Wild
RWD in the Wild
Rich Quick905 views
Introduction to Ruby on Rails by Diki Andeas
Introduction to Ruby on RailsIntroduction to Ruby on Rails
Introduction to Ruby on Rails
Diki Andeas1.3K views
15 Drupal Modules You've Probably Overlooked but Shouldn't by Chris Sloan
15 Drupal Modules You've Probably Overlooked but Shouldn't15 Drupal Modules You've Probably Overlooked but Shouldn't
15 Drupal Modules You've Probably Overlooked but Shouldn't
Chris Sloan4.5K views
Ruby on Rails + AngularJS + Twitter Bootstrap by Marcio Marinho
Ruby on Rails + AngularJS + Twitter BootstrapRuby on Rails + AngularJS + Twitter Bootstrap
Ruby on Rails + AngularJS + Twitter Bootstrap
Marcio Marinho3K views
JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D... by JavaScripters Community
JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...
JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS by murtazahaveliwala
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
murtazahaveliwala777 views

More from Matt Raible

Micro Frontends for Java Microservices - Belfast JUG 2022 by
Micro Frontends for Java Microservices - Belfast JUG 2022Micro Frontends for Java Microservices - Belfast JUG 2022
Micro Frontends for Java Microservices - Belfast JUG 2022Matt Raible
26 views57 slides
Micro Frontends for Java Microservices - Dublin JUG 2022 by
Micro Frontends for Java Microservices - Dublin JUG 2022Micro Frontends for Java Microservices - Dublin JUG 2022
Micro Frontends for Java Microservices - Dublin JUG 2022Matt Raible
19 views56 slides
Micro Frontends for Java Microservices - Cork JUG 2022 by
Micro Frontends for Java Microservices - Cork JUG 2022Micro Frontends for Java Microservices - Cork JUG 2022
Micro Frontends for Java Microservices - Cork JUG 2022Matt Raible
7 views56 slides
Comparing Native Java REST API Frameworks - Seattle JUG 2022 by
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
49 views87 slides
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022 by
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
105 views42 slides
Comparing Native Java REST API Frameworks - Devoxx France 2022 by
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
130 views86 slides

More from Matt Raible(20)

Micro Frontends for Java Microservices - Belfast JUG 2022 by Matt Raible
Micro Frontends for Java Microservices - Belfast JUG 2022Micro Frontends for Java Microservices - Belfast JUG 2022
Micro Frontends for Java Microservices - Belfast JUG 2022
Matt Raible26 views
Micro Frontends for Java Microservices - Dublin JUG 2022 by Matt Raible
Micro Frontends for Java Microservices - Dublin JUG 2022Micro Frontends for Java Microservices - Dublin JUG 2022
Micro Frontends for Java Microservices - Dublin JUG 2022
Matt Raible19 views
Micro Frontends for Java Microservices - Cork JUG 2022 by Matt Raible
Micro Frontends for Java Microservices - Cork JUG 2022Micro Frontends for Java Microservices - Cork JUG 2022
Micro Frontends for Java Microservices - Cork JUG 2022
Matt Raible7 views
Comparing Native Java REST API Frameworks - Seattle JUG 2022 by Matt Raible
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
Matt Raible49 views
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022 by Matt Raible
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
Matt Raible105 views
Comparing Native Java REST API Frameworks - Devoxx France 2022 by Matt Raible
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
Matt Raible130 views
Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne... by Matt 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...
Matt Raible98 views
Java REST API Framework Comparison - PWX 2021 by Matt Raible
Java REST API Framework Comparison - PWX 2021Java REST API Framework Comparison - PWX 2021
Java REST API Framework Comparison - PWX 2021
Matt Raible148 views
Web App Security for Java Developers - PWX 2021 by Matt Raible
Web App Security for Java Developers - PWX 2021Web App Security for Java Developers - PWX 2021
Web App Security for Java Developers - PWX 2021
Matt Raible135 views
Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ... by Matt 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 ...
Matt Raible187 views
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker... by 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...
Matt Raible140 views
Web App Security for Java Developers - UberConf 2021 by Matt Raible
Web App Security for Java Developers - UberConf 2021Web App Security for Java Developers - UberConf 2021
Web App Security for Java Developers - UberConf 2021
Matt Raible152 views
Java REST API Framework Comparison - UberConf 2021 by Matt Raible
Java REST API Framework Comparison - UberConf 2021Java REST API Framework Comparison - UberConf 2021
Java REST API Framework Comparison - UberConf 2021
Matt Raible150 views
Native Java with Spring Boot and JHipster - SF JUG 2021 by Matt Raible
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
Matt Raible69 views
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin... by Matt 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...
Matt Raible182 views
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021 by Matt Raible
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
Matt Raible182 views
Get Hip with JHipster - Colorado Springs Open Source User Group 2021 by Matt Raible
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
Matt Raible150 views
JHipster and Okta - JHipster Virtual Meetup December 2020 by Matt Raible
JHipster and Okta - JHipster Virtual Meetup December 2020JHipster and Okta - JHipster Virtual Meetup December 2020
JHipster and Okta - JHipster Virtual Meetup December 2020
Matt Raible226 views
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020 by Matt Raible
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
Matt Raible434 views
Security Patterns for Microservice Architectures - SpringOne 2020 by Matt Raible
Security Patterns for Microservice Architectures - SpringOne 2020Security Patterns for Microservice Architectures - SpringOne 2020
Security Patterns for Microservice Architectures - SpringOne 2020
Matt Raible329 views

Recently uploaded

Unlocking Research Visibility.pdf by
Unlocking Research Visibility.pdfUnlocking Research Visibility.pdf
Unlocking Research Visibility.pdfKhatirNaima
11 views19 slides
ASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdf by
ASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdfASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdf
ASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdfAlhamduKure
10 views11 slides
Robotics in construction enterprise by
Robotics in construction enterpriseRobotics in construction enterprise
Robotics in construction enterpriseKhalid Abdel Naser Abdel Rahim
5 views1 slide
AWS A5.18 A5.18M-2021.pdf by
AWS A5.18 A5.18M-2021.pdfAWS A5.18 A5.18M-2021.pdf
AWS A5.18 A5.18M-2021.pdfThinhNguyen455948
8 views48 slides
Plant Design Report-Oil Refinery.pdf by
Plant Design Report-Oil Refinery.pdfPlant Design Report-Oil Refinery.pdf
Plant Design Report-Oil Refinery.pdfSafeen Yaseen Ja'far
9 views10 slides
Créativité dans le design mécanique à l’aide de l’optimisation topologique by
Créativité dans le design mécanique à l’aide de l’optimisation topologiqueCréativité dans le design mécanique à l’aide de l’optimisation topologique
Créativité dans le design mécanique à l’aide de l’optimisation topologiqueLIEGE CREATIVE
8 views84 slides

Recently uploaded(20)

Unlocking Research Visibility.pdf by KhatirNaima
Unlocking Research Visibility.pdfUnlocking Research Visibility.pdf
Unlocking Research Visibility.pdf
KhatirNaima11 views
ASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdf by AlhamduKure
ASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdfASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdf
ASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdf
AlhamduKure10 views
Créativité dans le design mécanique à l’aide de l’optimisation topologique by LIEGE CREATIVE
Créativité dans le design mécanique à l’aide de l’optimisation topologiqueCréativité dans le design mécanique à l’aide de l’optimisation topologique
Créativité dans le design mécanique à l’aide de l’optimisation topologique
LIEGE CREATIVE8 views
2023Dec ASU Wang NETR Group Research Focus and Facility Overview.pptx by lwang78
2023Dec ASU Wang NETR Group Research Focus and Facility Overview.pptx2023Dec ASU Wang NETR Group Research Focus and Facility Overview.pptx
2023Dec ASU Wang NETR Group Research Focus and Facility Overview.pptx
lwang78188 views
REACTJS.pdf by ArthyR3
REACTJS.pdfREACTJS.pdf
REACTJS.pdf
ArthyR337 views
Web Dev Session 1.pptx by VedVekhande
Web Dev Session 1.pptxWeb Dev Session 1.pptx
Web Dev Session 1.pptx
VedVekhande20 views
BCIC - Manufacturing Conclave - Technology-Driven Manufacturing for Growth by Innomantra
BCIC - Manufacturing Conclave -  Technology-Driven Manufacturing for GrowthBCIC - Manufacturing Conclave -  Technology-Driven Manufacturing for Growth
BCIC - Manufacturing Conclave - Technology-Driven Manufacturing for Growth
Innomantra 20 views
Integrating Sustainable Development Goals (SDGs) in School Education by SheetalTank1
Integrating Sustainable Development Goals (SDGs) in School EducationIntegrating Sustainable Development Goals (SDGs) in School Education
Integrating Sustainable Development Goals (SDGs) in School Education
SheetalTank111 views
Design of machine elements-UNIT 3.pptx by gopinathcreddy
Design of machine elements-UNIT 3.pptxDesign of machine elements-UNIT 3.pptx
Design of machine elements-UNIT 3.pptx
gopinathcreddy38 views
Ansari: Practical experiences with an LLM-based Islamic Assistant by M Waleed Kadous
Ansari: Practical experiences with an LLM-based Islamic AssistantAnsari: Practical experiences with an LLM-based Islamic Assistant
Ansari: Practical experiences with an LLM-based Islamic Assistant
M Waleed Kadous11 views

The Art of AngularJS in 2015

  • 1. Photos by The Art of in 2015 Matt Raible • http://raibledesigns.com
  • 2. © 2014 Raible Designs Blogger on raibledesigns.com Founder of AppFuse Father, Skier, Mountain Biker, Whitewater Rafter Web Framework Connoisseur Who is Matt Raible? Bus Lover
  • 3. © 2015 Raible Designs Devoxx4Kids Denver • Teaching Kids to Program • Java, Minecraft, robots, oh my! • Non profit, looking for donations and speakers http://www.meetup.com/Devoxx4Kids-Denver/
  • 4. © 2015 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
  • 5. © 2015 Raible Designs Jobs on Dice.com January 2015 0 225 450 675 900 Backbone Angular Em ber Knockout React
  • 6. © 2015 Raible Designs LinkedIn Skills January 2015 0 25,000 50,000 75,000 100,000 Backbone Angular Knockout Em ber React
  • 7. © 2015 Raible Designs Google Trends
  • 8. © 2015 Raible Designs Indeed Job Trends Absolute Relative
  • 9. © 2015 Raible Designs Stack Overflow
  • 11. © 2015 Raible Designs Who wants to learn ?
  • 12. © 2015 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
  • 13. © 2015 Raible Designs The History of AngularJS 0 4500 9000 13500 18000 Lines of Code 17,000 1,000 AngularJS GWT
  • 14. © 2015 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.3.11/angular.min.js"></script> </body> </html>
  • 15. © 2015 Raible Designs Architecture Principles Structure Testability Boilerplate D.R.Y.
  • 16. © 2015 Raible Designs Code Organization Start with Angular Seed* * more options to be discussed later… git clone https://github.com/angular/angular-seed.git
  • 17. © 2015 Raible Designs Quick Demo
  • 18. © 2015 Raible Designs App Definition var app = angular.module('myApp', []); <!DOCTYPE html> <html ng-app="myApp">
  • 19. © 2015 Raible Designs App Definition with separate files app.js controllers.js angular.module('myApp', ['ngRoute', 'myApp.filters', 'myApp.services', 'myApp.directives', 'myApp.controllers' ]) angular.module('myApp.controllers', []). controller('MyCtrl1', [function() { }])
  • 20. © 2015 Raible Designs Model View Controller
  • 21. © 2015 Raible Designs Data Binding friend.js friend.html $scope.friend = { name: "Fernand" }; {{friend.name}} // 1-way <input ng-model="friend.name"> // 2-way
  • 22. © 2015 Raible Designs Solving FOUC This will work just fine — if it’s not on the first page: Use ng-cloak or ng-bind attribute: <p>{{friend.name}}</p> <p ng-cloak>{{friend.name}}</p> <p ng-bind="friend.name"></p>
  • 23. © 2015 Raible Designs Directives <div ng-repeat="entry in news.entries"> <span ng-bind="entry.title"></span> <button ng-click="delete($index)"> Delete </button> </div>
  • 24. © 2015 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>
  • 25. © 2015 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}}' }; });
  • 26. © 2015 Raible Designs Built-In Directives ng-href ng-src ng-disabled ng-checked ng-readonly ng-selected ng-class ng-style
  • 27. © 2015 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'}); });
  • 28. © 2015 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);
  • 29. © 2015 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 }; });
  • 30. © 2015 Raible Designs $q myApp.controller('HelloCtrl', function($scope, HelloWorld) { HelloWorld.getMessages().then(function(messages) { $scope.messages = messages; }); });
  • 31. © 2015 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("/"); }); }; })
  • 32. © 2015 Raible Designs Filters also: lowercase, limitTo, orderBy {{ 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' }}
  • 33. © 2015 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('!'); }] )
  • 34. © 2015 Raible Designs Routing: Navigation $rootScope.logout = function () { delete $rootScope.user; delete $http.defaults.headers.common[xAuthTokenHeaderName]; $cookieStore.remove('user'); $location.path("/login"); };
  • 35. © 2015 Raible Designs Routing: Navigation $rootScope.logout = function () { delete $rootScope.user; delete $http.defaults.headers.common[xAuthTokenHeaderName]; $cookieStore.remove('user'); $location.path("/login"); };
  • 36. © 2015 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
  • 39. Google's Recommendations for Angular App Structure
  • 41. © 2015 Raible Designs Testing Karma - test runner, framework agnostic Jasmine - unit tests, framework agnostic Protractor - integration tests, angular specific Lineman - productivity, framework agnostic
  • 42. © 2015 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 }); }));
  • 43. © 2015 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'); }); }); });
  • 44. © 2015 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); }); });
  • 45. © 2015 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
  • 46. © 2015 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"
  • 47. © 2015 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"
  • 48. © 2015 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}'] } },
  • 49. © 2015 Raible Designs Gruntfile.js useminPrepare: { html: 'app/index.html' }, usemin: { html: ['dist/index.html'] }, uglify: { options: { report: 'min', mangle: false } } });
  • 50. © 2015 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' ]); };
  • 51. © 2015 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>
  • 52. © 2015 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>
  • 53. © 2015 Raible Designs After Grunt http://raibledesigns.com/rd/entry/using_grunt_with_angularjs_for
  • 54. © 2015 Raible Designs You shouldn’t have to worry about FEO http://raibledesigns.com/rd/entry/you_shouldn_t_have_to
  • 55. © 2015 Raible Designs HTTP/2 Performance Anti-Patterns? Split dominant content domains Reduce requests Merging Sprites DataURIs http://www.slideshare.net/andydavies
  • 56. © 2015 Raible Designs UI Bootstrap http://angular-ui.github.io/bootstrap <script src="lib/angular/ui-bootstrap-0.12.0.min.js"></script> <script src="lib/angular/ui-bootstrap-tpls-0.12.0.min.js"></script> angular.module('myApp', ['ui.bootstrap']);
  • 57. © 2015 Raible Designs UI Bootstrap: Carousel
  • 58. © 2015 Raible Designs UI Bootstrap: Carousel <div ng-controller="CarouselDemoCtrl"> <div style="height: 305px"> <carousel interval="myInterval"> <slide ng-repeat="slide in slides" active="slide.active"> <img ng-src="{{slide.image}}" style="margin:auto;"> <div class="carousel-caption"> <h4>Slide {{$index}}</h4> <p>{{slide.text}}</p> </div> </slide> </carousel> </div> </div>
  • 59. © 2015 Raible Designs Foundation for Apps http://foundation.zurb.com/apps
  • 60. © 2015 Raible Designs Foundation
  • 61. © 2015 Raible Designs Foundation
  • 62. © 2015 Raible Designs Sass Mixins <div class="row"> <main class="medium-9 columns"> <p>Main content</p> </main> <aside class="medium-3 columns"> <p>Sidebar</p> </aside> </div>
  • 63. © 2015 Raible Designs Sass Mixins <div class="layout"> <main class="layout-content"> <p>Main content</p> </main> <aside class="layout-sidebar"> <p>Sidebar</p> </aside> </div>
  • 64. © 2015 Raible Designs Sass Mixins http://bit.ly/1Kh1ha5 @import "foundation/components/grid"; .layout { // `layout` container functions as a row @include grid-row(); } .layout-content { // Mobile-first: make `layout-container` full-width @include grid-column(12); // On medium-up size, make `layout-container` 9 columns wide @media #{$medium-up} { @include grid-column(9); } } .layout-sidebar { // Mobile-first: make `layout-sidebar` full-width @include grid-column(12); // On medium-up size, make `layout-sidebar` 3 columns wide @media #{$medium-up} { @include grid-column(3); } }
  • 65. © 2015 Raible Designs Ionic Framework http://ionicframework.com
  • 66. © 2015 Raible Designs#dv13javaweb$ My Ionic Experience http://raibledesigns.com/rd/entry/developing_an_ios_native_app
  • 67. © 2015 Raible Designs JHipster http://jhipster.github.io/
  • 68. © 2015 Raible Designs JHipster Spring Boot Spring Security AngularJS Bootstrap Bower Metrics Java 7 or Java 8 Maven or Gradle Authentication Type: cookie-based or OAuth2 Type of Database: SQL or NoSQL Caching: EhCache or Hazelcast Grunt or Gulp.js http://jhipster.github.io/ Foundational Frameworks Project Options
  • 69. © 2015 Raible Designs JHipster
  • 70. © 2015 Raible Designs JHipster: Metrics
  • 71. © 2015 Raible Designs JHipster: Code Generation
  • 72. © 2015 Raible Designs JHipster: Code Generation
  • 73. © 2015 Raible Designs AngularJS Batarang
  • 74. © 2015 Raible Designs My Experience in 2013 Developing with AngularJS Series Part I: The Basics
 Part II: Dialogs and Data
 Part III: Services
 Part IV: Making it Pop

  • 75. © 2015 Raible Designs#dv13javaweb$ My Experience in 2013 http://vimeo.com/mraible/angularjs-deep-dive
  • 76. © 2015 Raible Designs 2015 AngularJS Tutorials Getting Started with AngularJS http://raibledesigns.com/rd/entry/getting_started_with_angularjs Testing AngularJS Applications http://raibledesigns.com/rd/entry/testing_angularjs_applications
  • 77. © 2015 Raible Designs Spring and AngularJS http://spring.io/blog http://spring.io/blog/2015/01/12/spring-and-angular-js-a-secure-single-page-application
  • 78. © 2015 Raible Designs Angular 2.0 <input type="text" [value]="firstName"> <button (click)="addPerson()">Add</button> <input type="checkbox" [checked]="someProperty">
  • 79. © 2015 Raible Designs Concepts Eliminated in 2.0 Controllers Directive Definition Object $scope angular.module jqLite
  • 80. © 2015 Raible Designs The Bad News No migration path from Angular 1.x to 2.0 Angular 1.3 will be supported for 1.5 - 2 years Will only support Evergreen Browsers (e.g. IE10+) Learn more on http://www.infoq.com/news/2014/10/angular-2-atscript
  • 82. © 2015 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
  • 83. © 2015 Raible Designs Shortcut to becoming an Angular Artist JUST DO IT.
  • 84. © 2015 Raible Designs Contact Me! http://raibledesigns.com @mraible Presentations http://slideshare.net/mraible Code http://github.com/mraible Questions?
  • 85. © 2015 Raible Designs Who to follow on Twitter AngularJS Team at Google Miško Hevery - @mhevery Igor Minar - @IgorMinar Brian Ford - @briantford Web Performance Ilya Grigorik - @igrigorik Andy Davis - @andydavies Steve Souders - @Souders
  • 86. © 2015 Raible Designs 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/ Resources
  • 87. © 2015 Raible Designs 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 Code