SlideShare a Scribd company logo
AngularJS application
architecture
Gabriele Falace
workshop 11.03.2015
Separation of Concerns
Rule of 1
● each component has 1 role
● 1 component per file
● each component has a single purpose
Separation of Concerns - example
Classifying concerns:
● Cross-Cutting and generic
○ logging
○ exception handling
● Cross-Cutting and feature-specific
○ a service fetching Customer data
● Features
○ Customer Controller
○ Customer Address widget
Consistent syntax
Many things can be done with different styles.
It is strongly recommended to stick with one,
especially when working in team!
Consistent syntax - example
It is often needed to create an alias for the this
reference.
WHY: in JavaScript a scope is created by a
function definition (and not by {} blocks) →
while nesting function definitions, the reference
to the “original” this is lost.
Consistent syntax - example
function foo(){
this.x = 5;
// other code
function bar(){
// can’t access x through “this”
// this “this” belongs to bar
this.x = 6;
}
}
Consistent syntax - example
function foo(){
var self = this;
self.x = 5;
// other code
function bar(){
// can access “external” x through “self”
this.x = 6;
console.log(self.x);
}
}
Consistent syntax - example
widely used aliases
● in controllers: var vm = this; // view model
● in general js: var self = this;
Consistent syntax - services
angular.module('globalServices')
.service('paymentService', PaymentService); // a service is a SINGLETON
/* @ngInject */
function PaymentService($http, tokenService){
var service = {
validateCardNumber: validateCardNumber,
properCardNumberLength: properCardNumberLength
};
return service;
// implementation
}
Organizing the App
can be by type of by feature
by type can be ok for small-medium
sized apps.
When the size grows this gets confusing.
larger app → by feature, then by type
naming conventions
Controllers: avoid the suffix “Controller” use
uppercase for the function name (it’s a
constructor)
Factories/Services: same as file name
Directives: same as file name + short and
consistent prefix (e.g. “eb”)
Modules
Modules
use angular.module() for both declaring and
fetching modules.
angular.module(‘app’, []); // CREATES
angular.module(‘app’); // FETCHES
var app = angular.module(‘app’, []); //not recommended
Modules
Aggregate dependencies, in order to avoid an
overly long list of dependencies in our
modules.
Use a root “app.core” module to aggregate 3rd
party and other generic modules.
Controllers
Controllers
● only presentation logic in here
● don’t use anonymous functions
● use the “Controller As” syntax with “this”
instead of scope
● separate registration, injection, declaration
angular.module(‘app’).controller(‘foo’, Foo);
Foo.$inject = [‘$http’, ‘$scope’];
function Foo($http, $scope){ … }
Controllers
Declare the “Controller As” in ngRoutes,
whenever possible, also using resolve for
bootstrapping logic
controller: ‘Controller’
controllerAs: ‘ctrl’
resolve: {
message: [‘customerService’, function(customerService) {
return customerService.getGreetingMessage();
}]
}
Controllers
The controller can be injected with “message”
before the controller is instantiated → good
mechanism for bootstrapping logic, better than
“app.run” when logic should be specific to the
controller
Controller.$inject = [‘message’];
function Controller(message){ … }
AJAX - sequential requests
$http.get(PRICELIST_URL)
.then(function (data) {
pricelist = data['data'];
console.log('AFTER CALL 1 __ ' + pricelist + '(pricelist)');
return $http.get(CURRENCY_URL);
})
.then(function (data) {
currency = data['data'];
var actualUrl = TARIFFS_URL.replace('{priceListId}', pricelist);
return $http.get(actualUrl);
})
.then(function (data){
console.log('AFTER CALL 3 __ (tariffs) n' + JSON.stringify(data['data']));
});
AJAX - parallel requests
$q.all([fn1(), fn2(),]);
array of functions each returning a Promise
function fn1(){
return $http.get(SERVICE_URL);
}
Tips
using value/constant to keep everything in the
scope of the application. constants and values
can be injected.
angular.module('application').constant('origin', 'Sydney');
service('simpleService', ['origin', function (origin) {
// implementation ...
}
Tips
It’s usually nice to consider …
● using ngAnnotate (e.g. /* @ngInject */)
● using jshint (to impose some coding style)
● using JavaScript
○ especially iterators over arrays:
■ someArray.forEach(fn)
■ someArray.filter(fn)
■ someArray.some(fn)
■ someArray.every(fn)
■ someArray.map(fn)
Unit Testing - installation
● choose a framework (e.g. Jasmine)
● choose a test runner (e.g. Karma)
● setup:
npm install -g karma
npm install -g karma-cli
in the project folder run the following
karma init
Unit Testing - configuring
● in the project root a karma.conf.js file
specifies settings for the tests
○ make sure that the file property in the file references an array of file
path where the JS app file and the test are located!
● Typically, most important things to test are
Services, as they’re the components which
hold business logic
Unit Testing - example
describe('testPaymentService', function () {
var paymentService, $httpBackend;
beforeEach(module('globalServices'));
beforeEach(function () {
inject(function($injector){
$httpBackend = $injector.get('$httpBackend');
paymentService = $injector.get('paymentService');
});
});
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should check mastercard', function () {
$httpBackend
.when('GET', REST_API_URL + '/services/payment/validateCreditCard/5105105105105100')
.respond('MASTERCARD');
var res = paymentService.validateCardNumber('5105105105105100');
$httpBackend.flush();
expect(res.$$state.value.data).toEqual('MASTERCARD');
});
});
E2E Testing - installation
● choose a framework (e.g. Jasmine)
● choose a test runner (e.g. Protractor)
● setup:
npm install -g protractor
in the project folder run the following, to start the
Selenium WebDriver
webdriver-manager start
Configuring
create the configuration file. Copy the following into conf.js:
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['todo-spec.js']
};
This configuration tells Protractor where your test files (specs) are, and where to talk to your Selenium
Server (seleniumAddress).
Write a test
A protractor test, manipulates the actual elements in the app launching the browser and picking up
stuff in the page through matchers. Run it with protractor conf.js
describe('Ebuero CSW number fields validation', function () {
beforeEach(function () {
browser.sleep(2000);
browser.get(URL);
...
});
it('should format, validate and copy the phone, mobile and fax number', function () {
companyName.sendKeys('000TEST000 ebuero AG');
...
expect(faxNumber.getAttribute('value')).toBe(FORMATTED_PHONE_NUMBER);
element(by.cssContainingText('option', 'AG')).click();
nextButton1.click();
expect(createErrorBox.isDisplayed()).toBeFalsy();
});
});
References
● John Papa’s course on PluralSight
● Style guide: https://github.com/johnpapa/angular-styleguide
● More on Services, Providers: http://slides.wesalvaro.com/20121113/#/2/5
● Possible JSON security threat: http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-
json-vulnerability.aspx/

More Related Content

What's hot (20)

PDF
AngularJS Basics and Best Practices - CC FE &UX
JWORKS powered by Ordina
 
ODP
AngularJs Crash Course
Keith Bloomfield
 
PPTX
Angular js
Manav Prasad
 
PDF
AngularJS Best Practices
Betclic Everest Group Tech Team
 
PPTX
The AngularJS way
Boyan Mihaylov
 
PPTX
AngularJS Best Practices
Narek Mamikonyan
 
PPTX
Angular JS - Introduction
Sagar Acharya
 
PPTX
AngularJs presentation
Phan Tuan
 
PPTX
AngularJS - The Next Big Thing?
Tom Hombergs
 
PPTX
Introduction to Angular js 2.0
Nagaraju Sangam
 
PDF
AngularJS 101 - Everything you need to know to get started
Stéphane Bégaudeau
 
PDF
AngularJS Project Setup step-by- step guide - RapidValue Solutions
RapidValue
 
PPTX
Angular js architecture (v1.4.8)
Gabi Costel Lapusneanu
 
PPTX
AngularJS - Architecture decisions in a large project 
Elad Hirsch
 
PPTX
Angular js tutorial slides
samhelman
 
PPTX
Angular js
Dinusha Nandika
 
PPTX
Front end development with Angular JS
Bipin
 
PDF
Angularjs - lazy loading techniques
Nir Kaufman
 
ODP
Angularjs
Vincenzo Ferrari
 
PPTX
Angular js
Behind D Walls
 
AngularJS Basics and Best Practices - CC FE &UX
JWORKS powered by Ordina
 
AngularJs Crash Course
Keith Bloomfield
 
Angular js
Manav Prasad
 
AngularJS Best Practices
Betclic Everest Group Tech Team
 
The AngularJS way
Boyan Mihaylov
 
AngularJS Best Practices
Narek Mamikonyan
 
Angular JS - Introduction
Sagar Acharya
 
AngularJs presentation
Phan Tuan
 
AngularJS - The Next Big Thing?
Tom Hombergs
 
Introduction to Angular js 2.0
Nagaraju Sangam
 
AngularJS 101 - Everything you need to know to get started
Stéphane Bégaudeau
 
AngularJS Project Setup step-by- step guide - RapidValue Solutions
RapidValue
 
Angular js architecture (v1.4.8)
Gabi Costel Lapusneanu
 
AngularJS - Architecture decisions in a large project 
Elad Hirsch
 
Angular js tutorial slides
samhelman
 
Angular js
Dinusha Nandika
 
Front end development with Angular JS
Bipin
 
Angularjs - lazy loading techniques
Nir Kaufman
 
Angularjs
Vincenzo Ferrari
 
Angular js
Behind D Walls
 

Similar to AngularJS application architecture (20)

ODP
Unit Testing and Coverage for AngularJS
Knoldus Inc.
 
PPTX
Protractor framework architecture with example
shadabgilani
 
PDF
Field injection, type safe configuration, and more new goodies in Declarative...
bjhargrave
 
PDF
Voorhoede - Front-end architecture
Jasper Moelker
 
PDF
How to write maintainable code without tests
Juti Noppornpitak
 
PDF
Angular Intermediate
LinkMe Srl
 
PDF
Build Web Apps using Node.js
davidchubbs
 
PDF
Javascript ui for rest services
Ioan Eugen Stan
 
ODP
Declarative Services - Dependency Injection OSGi Style
Felix Meschberger
 
ODP
Declarative Services - Dependency Injection OSGi Style
Felix Meschberger
 
PPTX
Angular training - Day 3 - custom directives, $http, $resource, setup with ye...
murtazahaveliwala
 
PDF
Angular.js Primer in Aalto University
SC5.io
 
PDF
Language enhancements in cold fusion 11
ColdFusionConference
 
PDF
TypeScript for Java Developers
Yakov Fain
 
PDF
Workshop 23: ReactJS, React & Redux testing
Visual Engineering
 
PDF
dokumen.tips_rediscovering-spring-with-spring-boot1 (1).pdf
Appster1
 
PDF
dokumen.tips_rediscovering-spring-with-spring-boot1.pdf
Appster1
 
KEY
How and why i roll my own node.js framework
Ben Lin
 
PDF
SCR Annotations for Fun and Profit
Mike Pfaff
 
PPTX
Osgi
Heena Madan
 
Unit Testing and Coverage for AngularJS
Knoldus Inc.
 
Protractor framework architecture with example
shadabgilani
 
Field injection, type safe configuration, and more new goodies in Declarative...
bjhargrave
 
Voorhoede - Front-end architecture
Jasper Moelker
 
How to write maintainable code without tests
Juti Noppornpitak
 
Angular Intermediate
LinkMe Srl
 
Build Web Apps using Node.js
davidchubbs
 
Javascript ui for rest services
Ioan Eugen Stan
 
Declarative Services - Dependency Injection OSGi Style
Felix Meschberger
 
Declarative Services - Dependency Injection OSGi Style
Felix Meschberger
 
Angular training - Day 3 - custom directives, $http, $resource, setup with ye...
murtazahaveliwala
 
Angular.js Primer in Aalto University
SC5.io
 
Language enhancements in cold fusion 11
ColdFusionConference
 
TypeScript for Java Developers
Yakov Fain
 
Workshop 23: ReactJS, React & Redux testing
Visual Engineering
 
dokumen.tips_rediscovering-spring-with-spring-boot1 (1).pdf
Appster1
 
dokumen.tips_rediscovering-spring-with-spring-boot1.pdf
Appster1
 
How and why i roll my own node.js framework
Ben Lin
 
SCR Annotations for Fun and Profit
Mike Pfaff
 
Ad

Recently uploaded (20)

PDF
From Chatbot to Destroyer of Endpoints - Can ChatGPT Automate EDR Bypasses (1...
Priyanka Aash
 
DOCX
Daily Lesson Log MATATAG ICT TEchnology 8
LOIDAALMAZAN3
 
PPTX
Smarter Governance with AI: What Every Board Needs to Know
OnBoard
 
PPTX
reInforce 2025 Lightning Talk - Scott Francis.pptx
ScottFrancis51
 
PPTX
𝙳𝚘𝚠𝚗𝚕𝚘𝚊𝚍—Wondershare Filmora Crack 14.0.7 + Key Download 2025
sebastian aliya
 
PDF
Python Conference Singapore - 19 Jun 2025
ninefyi
 
PPTX
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
PDF
Kubernetes - Architecture & Components.pdf
geethak285
 
PPTX
MARTSIA: A Tool for Confidential Data Exchange via Public Blockchain - Poster...
Michele Kryston
 
PDF
Plugging AI into everything: Model Context Protocol Simplified.pdf
Abati Adewale
 
PPSX
Usergroup - OutSystems Architecture.ppsx
Kurt Vandevelde
 
PDF
FME as an Orchestration Tool with Principles From Data Gravity
Safe Software
 
PDF
Automating the Geo-Referencing of Historic Aerial Photography in Flanders
Safe Software
 
PPTX
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
pcprocore
 
PDF
Open Source Milvus Vector Database v 2.6
Zilliz
 
PDF
The Future of Product Management in AI ERA.pdf
Alyona Owens
 
PPTX
01_Approach Cyber- DORA Incident Management.pptx
FinTech Belgium
 
PDF
Hyderabad MuleSoft In-Person Meetup (June 21, 2025) Slides
Ravi Tamada
 
PPTX
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
PPTX
Curietech AI in action - Accelerate MuleSoft development
shyamraj55
 
From Chatbot to Destroyer of Endpoints - Can ChatGPT Automate EDR Bypasses (1...
Priyanka Aash
 
Daily Lesson Log MATATAG ICT TEchnology 8
LOIDAALMAZAN3
 
Smarter Governance with AI: What Every Board Needs to Know
OnBoard
 
reInforce 2025 Lightning Talk - Scott Francis.pptx
ScottFrancis51
 
𝙳𝚘𝚠𝚗𝚕𝚘𝚊𝚍—Wondershare Filmora Crack 14.0.7 + Key Download 2025
sebastian aliya
 
Python Conference Singapore - 19 Jun 2025
ninefyi
 
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
Kubernetes - Architecture & Components.pdf
geethak285
 
MARTSIA: A Tool for Confidential Data Exchange via Public Blockchain - Poster...
Michele Kryston
 
Plugging AI into everything: Model Context Protocol Simplified.pdf
Abati Adewale
 
Usergroup - OutSystems Architecture.ppsx
Kurt Vandevelde
 
FME as an Orchestration Tool with Principles From Data Gravity
Safe Software
 
Automating the Geo-Referencing of Historic Aerial Photography in Flanders
Safe Software
 
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
pcprocore
 
Open Source Milvus Vector Database v 2.6
Zilliz
 
The Future of Product Management in AI ERA.pdf
Alyona Owens
 
01_Approach Cyber- DORA Incident Management.pptx
FinTech Belgium
 
Hyderabad MuleSoft In-Person Meetup (June 21, 2025) Slides
Ravi Tamada
 
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
Curietech AI in action - Accelerate MuleSoft development
shyamraj55
 
Ad

AngularJS application architecture

  • 2. Separation of Concerns Rule of 1 ● each component has 1 role ● 1 component per file ● each component has a single purpose
  • 3. Separation of Concerns - example Classifying concerns: ● Cross-Cutting and generic ○ logging ○ exception handling ● Cross-Cutting and feature-specific ○ a service fetching Customer data ● Features ○ Customer Controller ○ Customer Address widget
  • 4. Consistent syntax Many things can be done with different styles. It is strongly recommended to stick with one, especially when working in team!
  • 5. Consistent syntax - example It is often needed to create an alias for the this reference. WHY: in JavaScript a scope is created by a function definition (and not by {} blocks) → while nesting function definitions, the reference to the “original” this is lost.
  • 6. Consistent syntax - example function foo(){ this.x = 5; // other code function bar(){ // can’t access x through “this” // this “this” belongs to bar this.x = 6; } }
  • 7. Consistent syntax - example function foo(){ var self = this; self.x = 5; // other code function bar(){ // can access “external” x through “self” this.x = 6; console.log(self.x); } }
  • 8. Consistent syntax - example widely used aliases ● in controllers: var vm = this; // view model ● in general js: var self = this;
  • 9. Consistent syntax - services angular.module('globalServices') .service('paymentService', PaymentService); // a service is a SINGLETON /* @ngInject */ function PaymentService($http, tokenService){ var service = { validateCardNumber: validateCardNumber, properCardNumberLength: properCardNumberLength }; return service; // implementation }
  • 10. Organizing the App can be by type of by feature by type can be ok for small-medium sized apps. When the size grows this gets confusing. larger app → by feature, then by type
  • 11. naming conventions Controllers: avoid the suffix “Controller” use uppercase for the function name (it’s a constructor) Factories/Services: same as file name Directives: same as file name + short and consistent prefix (e.g. “eb”)
  • 13. Modules use angular.module() for both declaring and fetching modules. angular.module(‘app’, []); // CREATES angular.module(‘app’); // FETCHES var app = angular.module(‘app’, []); //not recommended
  • 14. Modules Aggregate dependencies, in order to avoid an overly long list of dependencies in our modules. Use a root “app.core” module to aggregate 3rd party and other generic modules.
  • 16. Controllers ● only presentation logic in here ● don’t use anonymous functions ● use the “Controller As” syntax with “this” instead of scope ● separate registration, injection, declaration angular.module(‘app’).controller(‘foo’, Foo); Foo.$inject = [‘$http’, ‘$scope’]; function Foo($http, $scope){ … }
  • 17. Controllers Declare the “Controller As” in ngRoutes, whenever possible, also using resolve for bootstrapping logic controller: ‘Controller’ controllerAs: ‘ctrl’ resolve: { message: [‘customerService’, function(customerService) { return customerService.getGreetingMessage(); }] }
  • 18. Controllers The controller can be injected with “message” before the controller is instantiated → good mechanism for bootstrapping logic, better than “app.run” when logic should be specific to the controller Controller.$inject = [‘message’]; function Controller(message){ … }
  • 19. AJAX - sequential requests $http.get(PRICELIST_URL) .then(function (data) { pricelist = data['data']; console.log('AFTER CALL 1 __ ' + pricelist + '(pricelist)'); return $http.get(CURRENCY_URL); }) .then(function (data) { currency = data['data']; var actualUrl = TARIFFS_URL.replace('{priceListId}', pricelist); return $http.get(actualUrl); }) .then(function (data){ console.log('AFTER CALL 3 __ (tariffs) n' + JSON.stringify(data['data'])); });
  • 20. AJAX - parallel requests $q.all([fn1(), fn2(),]); array of functions each returning a Promise function fn1(){ return $http.get(SERVICE_URL); }
  • 21. Tips using value/constant to keep everything in the scope of the application. constants and values can be injected. angular.module('application').constant('origin', 'Sydney'); service('simpleService', ['origin', function (origin) { // implementation ... }
  • 22. Tips It’s usually nice to consider … ● using ngAnnotate (e.g. /* @ngInject */) ● using jshint (to impose some coding style) ● using JavaScript ○ especially iterators over arrays: ■ someArray.forEach(fn) ■ someArray.filter(fn) ■ someArray.some(fn) ■ someArray.every(fn) ■ someArray.map(fn)
  • 23. Unit Testing - installation ● choose a framework (e.g. Jasmine) ● choose a test runner (e.g. Karma) ● setup: npm install -g karma npm install -g karma-cli in the project folder run the following karma init
  • 24. Unit Testing - configuring ● in the project root a karma.conf.js file specifies settings for the tests ○ make sure that the file property in the file references an array of file path where the JS app file and the test are located! ● Typically, most important things to test are Services, as they’re the components which hold business logic
  • 25. Unit Testing - example describe('testPaymentService', function () { var paymentService, $httpBackend; beforeEach(module('globalServices')); beforeEach(function () { inject(function($injector){ $httpBackend = $injector.get('$httpBackend'); paymentService = $injector.get('paymentService'); }); }); afterEach(function() { $httpBackend.verifyNoOutstandingExpectation(); $httpBackend.verifyNoOutstandingRequest(); }); it('should check mastercard', function () { $httpBackend .when('GET', REST_API_URL + '/services/payment/validateCreditCard/5105105105105100') .respond('MASTERCARD'); var res = paymentService.validateCardNumber('5105105105105100'); $httpBackend.flush(); expect(res.$$state.value.data).toEqual('MASTERCARD'); }); });
  • 26. E2E Testing - installation ● choose a framework (e.g. Jasmine) ● choose a test runner (e.g. Protractor) ● setup: npm install -g protractor in the project folder run the following, to start the Selenium WebDriver webdriver-manager start
  • 27. Configuring create the configuration file. Copy the following into conf.js: exports.config = { seleniumAddress: 'http://localhost:4444/wd/hub', specs: ['todo-spec.js'] }; This configuration tells Protractor where your test files (specs) are, and where to talk to your Selenium Server (seleniumAddress).
  • 28. Write a test A protractor test, manipulates the actual elements in the app launching the browser and picking up stuff in the page through matchers. Run it with protractor conf.js describe('Ebuero CSW number fields validation', function () { beforeEach(function () { browser.sleep(2000); browser.get(URL); ... }); it('should format, validate and copy the phone, mobile and fax number', function () { companyName.sendKeys('000TEST000 ebuero AG'); ... expect(faxNumber.getAttribute('value')).toBe(FORMATTED_PHONE_NUMBER); element(by.cssContainingText('option', 'AG')).click(); nextButton1.click(); expect(createErrorBox.isDisplayed()).toBeFalsy(); }); });
  • 29. References ● John Papa’s course on PluralSight ● Style guide: https://github.com/johnpapa/angular-styleguide ● More on Services, Providers: http://slides.wesalvaro.com/20121113/#/2/5 ● Possible JSON security threat: http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle- json-vulnerability.aspx/