SlideShare a Scribd company logo
HOW ANGULAR
CAN SOLVE
ALL YOUR PROBLEMS
Nir Kaufman
IT CAN’T
Nir Kaufman
- I don’t really need glasses to see
- This photo is a photoshop
- In reality I’m in color (and fatter)
Head of AngularJS Development @ 500Tech
INTRODUCTION
“We are not happy with our app.
it should be modular,
easy to extend and maintain.
It’s hard to understand the flow,
feels like a spaghetti
of presentation and business logic.
- frontend team at {{ company.name }}
WE NEED A BETTER
FRAMEWORK
WHAT DO WE NEED?
COMPONENTS
A clean way of organizing
your UI code into self-contained,
reusable chunks
// component controller

class likeBoxController {



constructor(params) {

this.chosenValue = params.value;

}



like() {

this.chosenValue('like');

}



dislike() {

this.chosenValue('dislike');

}

}



// component definition

function likeBoxComponent() {

return {

viewModel: likeBoxController,

template: likeBoxTemplate

}

}



// component registration

ko.components.register('like-widget', likeBoxComponent());
// component controller

class likeBoxController {



constructor() {

this.chosenValue = null;

}



like() {

this.chosenValue = 'like';

}



dislike() {

this.chosenValue = 'dislike';

}

}



// component definition

function likeBoxComponent() {

return {

controller: likeBoxController,

scope: { params: ‘=chosenValue' },

controllerAs: 'LikeBox',

bindToController: true,

template: likeBoxTemplate

}

}



angular.module('app', [])

.directive('likeWidget', likeBoxComponent);
<div class="like-or-dislike" data-bind="visible: !chosenValue()">

<button data-bind="click: like">Like it</button>

<button data-bind="click: dislike">Dislike it</button>

</div>



<div class="result" data-bind="visible: chosenValue">

You <strong data-bind="text: chosenValue"></strong> it

</div>
<div class="like-or-dislike" ng-hide="LikeBox.chosenValue">

<button ng-click="LikeBox.like()">Like it</button>

<button ng-click="LikeBox.dislike()">Dislike it</button>

</div>



<div class="result" ng-show="LikeBox.chosenValue">

You <strong ng-bind="LikeBox.chosenValue"></strong> it

</div>

class LikeWidget extends React.Component {



constructor(props) {

super(props);



this.state = { chosenValue: null };



this.like = this.like.bind(this);

this.dislike = this.dislike.bind(this);

this._likeButtons = this._likeButtons.bind(this)

}



like() {

this.setState({

chosenValue: 'like'

})

}



dislike() {

this.setState({

chosenValue: 'dislike'

})

}





_likeButtons() {

if (this.state.chosenValue) {

return null

}



return (

<div>

<button onClick={this.like}>Like it</button>

<button onClick={this.dislike}>Dislike it</button>

</div>

)

}



render() {

return (

<div>

{ this._likeButtons() }

{ this.state.chosenValue ?

<div>You <strong>{ this.state.chosenValue }</strong> it </div> : null}

</div>

)

}

}



React.render(<LikeWidget/>, document.getElementById('app'));
MVW PATTERN
Keep your business logic
separate from your user interface
class MyViewModel {



constructor() {

this.products = [

new Product('Garlic bread'),

new Product('Pain au chocolat'),

new Product('Seagull spaghetti', 'like')

];

}

}



ko.applyBindings(new MyViewModel());
class MyViewModel {



constructor() {

this.products = [

new Product('Garlic bread'),

new Product('Pain au chocolat'),

new Product('Seagull spaghetti', 'like')

];

}

}



angular.module('app', [])

.controller('MyViewModel', MyViewModel);
Backbone.Model.extend({

defaults: {

coverImage: 'img/placeholder.png',

title: 'No title',

author: 'Unknown',

releaseDate: 'Unknown',

keywords: 'None'

}

});
DS.Model.extend({

title: DS.attr('No title'),

author: DS.attr('Unknown'),

releaseDate: DS.attr('Unknown'),

keywords: DS.attr('None')

});
class Book {

constructor() {

this.coverImage = 'img/placeholder.png';

this.title = 'No title';

this.author = 'Unknown';

this.releaseDate = 'Unknown';

this.keywords = 'None';

}

}
LETS GET TO THE POINT
All major frameworks introduce
the same concepts.
Don’t make a switch for the
wrong reasons. Switching
to another framework won’t
solve your design problems.
OBJECT ORIENTED
PROGRAMMING
CONSIDER TYPESCRIPT
I used to hate it…
SOLID PRINCIPLES
Single Responsibility
Open / Closed
Liskov Substitution
Interface Segregation
Dependency Inversion
S.O.L.I.D
Single Responsibility Principle
A module should have one,
and only one reason to change
// module declarations

angular.module('app', [

'ui.router',

'LocalStorageModule',

'app.states'

])

.config(($stateProvider, $httpProvider, localStorageServiceProvider) => {



// start routing

$stateProvider

.state('dashboard', {

url: '/dashboard',

templateUrl: 'states/dashboard/dashboard.html',

controller: 'DashboardController'

})



.state('users', {

url: '/users',

templateUrl: 'states/users/users.html',

controller: 'UsersController'

});



// http configuration

$httpProvider.useApplyAsync(true);

$httpProvider.useLegacyPromiseExtensions(false);



$httpProvider.interceptors.push(($log) => {

return {

'request': function (config) {

$log.debug(config);

return config;

}

};

});



// storage configurations

localStorageServiceProvider

.setPrefix('myApp')

.setStorageType('sessionStorage')

});



// start engines

angular.bootstrap(document, ['app']);
4 reasons
to change
this module:
add dependency
add new state
configure http service
configure storage service
// module declarations

angular.module('app', [

'ui.router',

'LocalStorageModule',

'app.states'

])

.config(routes)

.config(http)

.config(storage)



// start engines

angular.bootstrap(document, ['app']);
export function routes($stateProvider) {

$stateProvider

.state('dashboard', {

url: '/dashboard',

templateUrl: 'states/dashboard/dashboard.html',

controller: 'DashboardController'

})



.state('users', {

url: '/users',

templateUrl: 'states/users/users.html',

controller: 'UsersController'

});

}

routes.ts
app.ts
export function http ($httpProvider) {

$httpProvider.useApplyAsync(true);

$httpProvider.useLegacyPromiseExtensions(false);

}
http.ts
export function storage(localStorageServiceProvider) {

localStorageServiceProvider

.setPrefix('myApp')

.setStorageType('sessionStorage')

}
storage.ts
// module declarations

angular.module('app', [

'ui.router',

'LocalStorageModule',

'app.states'

])

.config(routes)

.config(http)

.config(storage)



// start engines

angular.bootstrap(document, ['app']);
Are we there yet?
2 reasons to change
// module declarations

angular.module('app', [

'ui.router',

'LocalStorageModule',

'app.states'

])

// start engines

angular.bootstrap(document, ['app']);
1 responsibility
S.O.L.I.D
Open / Closed Principle
A module should be open for
extension, but closed for
modification.
class Modal {



constructor($modal) {

this.modal = $modal;

}



show(type) {



switch (type) {

case 'login':

this.showLoginModal();

break;

case 'info':

this.showInfoModal();

break;

}

}



showLoginModal() {

this.modal.open({

template: 'loginModal.html',

controller: ‘loginModalController’

})

}



showInfoModal() {

this.modal.open({

template: 'infoModal.html',

controller: 'infoModalController'

})

}

}
class Controller {



constructor(Modal) {

this.Modal = Modal;

}



showLogin(){

this.Modal.show('login');

}

}
We need to add
new Modals to
our system
class Modal {



constructor($modal) {

this.modal = $modal;

this.modals = new Map();

}



register(type, config) {

this.modals.set(type, config)

}



$get() {

return { show: this.show }

}



show(type) {

if(this.modals.has(type)){

this.modal.open(this.modals.get(type))

}

}

}

angular.module('app', [])

.config(ModalProvider => {



ModalProvider.register('lostPassword', {

template: 'lostPassword.html',

controller: 'lostPasswordController'

})

});
class Controller {



constructor(Modal) {

this.Modal = Modal;

}



showLogin(){

this.Modal.show('lostPassword');

}

}
Write code that
can be extended
S.O.L.I.D
Liskov Substitution Principle
Child classes should never
break the parent class type definitions
IT’S ABOUT
INHERITANCE
DON’T DO IT
S.O.L.I.D
Interface Segregation Principle
Many specific interfaces
are better than one generic interface
I just want to make a copy
class LocalStorage {

private storage;

private $window;



constructor($window, $q) {

this.$window = $window;

}



setStorageType(type:string) {

if (type === 'local') {

return this.storage = this.$window.localStorage;

}

if (type === 'db') {

return this.storage = new PouchDB('DB');

}

}



setLocalItem(key:string, data) {

if (this.db) {

return this.db.put(JSON.parse(data))

}

return this.storage.setItem(key, JSON.stringify(data));

}
put(data) {

this.storage.put(JSON.parse(data))

}


getLocalItem(key:string):string {

let deferred = this.$q.defer();



if (this.db) {

this.db.get(key).then( result => deferred.resolve() )

}

deferred.resolve(this.storage.getItem());

return deferred.promise;

}

}
No client should be
forced to depend on
methods it doesn’t use
class LocalStorage {

private storage;



constructor($window) {

this.storage = $window.localStorage;

}





setItem(key:string, data) {

return this.storage.setItem(key, JSON.stringify(data));

}



getItem(key:string):string {

return this.storage.getItem();

}

}
class SessionStorage {

private storage;



constructor($window, $q) {

this.storage = $window.sessionStorage;

}



setItem(key:string, data) {

return this.storage.setItem(key, JSON.stringify(data));

}



getItem(key:string):string {

return this.storage.getItem();

}

}
localStorage.ts
sessionStorage.ts
class DBStorage {

private db;



constructor(PouchDB) {

this.db = new PouchDB('DB');

}



put(data) {

this.db.put(data)

}



get(id){

return this.db.get(id);

}

}
dbStorage.ts
UserComponent.ts (client)
class UserComponent {

private storage;



constructor(LocalStorage) {

this.storage = LocalStorage

}

}
S.O.L.I.D
Dependency Inversion Principle
High-level modules should not depend
on low-level modules. Both should
depend on abstractions.
NATIVE API’s
ANGULAR
3RD PARTY MODULES
APLLICATION CODE
INTERFACES
Application Layers
YOUR MODULES
Abstraction
Abstraction
interface IStorage {

setItem(key:string, data:any);

getItem(key:string, data:any);

}
IStorgae.ts UserComponent.ts (client)
class UserComponent {

private storage;



constructor(Storage: IStorage) {

this.storage = LocalStorage

}

}
LocalStorage.ts
class LocalStorage implements IStorage {

private storage;



constructor($window) {

this.storage = $window.localStorage;

}



setItem(key:string, data) {

return this.storage.setItem(key, JSON.stringify(data));

}



getItem(key:string):string {

return this.storage.getItem();

}

}
The ‘client’ can work
with any kind of storage
that implements the
IStorage interface
export class WelcomeController {



constructor($modal) {

this.$modal = $modal;

}



login() {

let loginModalInstance = this.$modal.open({

templateUrl: 'states/welcome/login_modal.html',

keyboard: false,

backdrop: 'static',

controller: LoginModalController,

controllerAs: 'Login'

});



loginModalInstance.result

.then(result => console.log(result))

}

}
Angular Bootstrap Modal
export class DashboardController {



constructor($modal) {

this.$modal = $modal;

}



showInfo() {

let infoModalInstance = this.$modal.open({

templateUrl: 'states/dashboard/info_modal.html',

keyboard: false,

backdrop: 'static',

controller: InfoModalController,

controllerAs: 'Info'

});



infoModalInstance.result

.then(result => console.log(result))

}

}
What is the problem?
class Modal {



constructor($modal) {

this.modal = $modal;

this.modals = new Map();

}



register(type, config) {

this.modals.set(type, config)

}



$get() {

return { show: this.show }

}



show(type) {

if(this.modals.has(type)){

this.modal.open(this.modals.get(type))

}

}

}

Abstraction without TypeScript
SUMMARY
DON’T MAKE A
SWITCH FOR
THE WRONG
REASONS
DESIGN PATTENS
MATTER
GOOD DESIGN
IS FRAMEWORK
AGNOSTIC
THANK YOU!
Angular ES6 / TypeScript Starters
https://github.com/nirkaufman/angular-webpack-starter
https://github.com/nirkaufman/angular-webpack-typescript-starter
resources
https://scotch.io/bar-talk/s-o-l-i-d-the-first-five-principles-of-object-oriented-design
http://code.tutsplus.com/series/the-solid-principles--cms-634
http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Read our blog:
http://blog.500tech.com
Nir Kaufman
nir@500tech.com

More Related Content

What's hot

Security misconfiguration
Security misconfigurationSecurity misconfiguration
Security misconfiguration
Micho Hayek
 
Angular Dependency Injection
Angular Dependency InjectionAngular Dependency Injection
Angular Dependency Injection
Nir Kaufman
 
A5-Security misconfiguration-OWASP 2013
A5-Security misconfiguration-OWASP 2013   A5-Security misconfiguration-OWASP 2013
A5-Security misconfiguration-OWASP 2013
Sorina Chirilă
 
Dom based xss
Dom based xssDom based xss
Dom based xssLê Giáp
 
Boto3
Boto3Boto3
Cross Site Scripting Defense Presentation
Cross Site Scripting Defense Presentation Cross Site Scripting Defense Presentation
Cross Site Scripting Defense Presentation
Ikhade Maro Igbape
 
Angular Advanced Routing
Angular Advanced RoutingAngular Advanced Routing
Angular Advanced Routing
Laurent Duveau
 
"15 Technique to Exploit File Upload Pages", Ebrahim Hegazy
"15 Technique to Exploit File Upload Pages", Ebrahim Hegazy"15 Technique to Exploit File Upload Pages", Ebrahim Hegazy
"15 Technique to Exploit File Upload Pages", Ebrahim Hegazy
HackIT Ukraine
 
Application Logging Good Bad Ugly ... Beautiful?
Application Logging Good Bad Ugly ... Beautiful?Application Logging Good Bad Ugly ... Beautiful?
Application Logging Good Bad Ugly ... Beautiful?
Anton Chuvakin
 
Garage4Hackers Ranchoddas Webcast Series - Bypassing Modern WAF's Exemplified...
Garage4Hackers Ranchoddas Webcast Series - Bypassing Modern WAF's Exemplified...Garage4Hackers Ranchoddas Webcast Series - Bypassing Modern WAF's Exemplified...
Garage4Hackers Ranchoddas Webcast Series - Bypassing Modern WAF's Exemplified...
Garage4hackers.com
 
Rest API Security
Rest API SecurityRest API Security
Rest API Security
Stormpath
 
9 element entry_validation_part_9
9 element entry_validation_part_99 element entry_validation_part_9
9 element entry_validation_part_9
Oracle HRMS Functional Consultant
 
OWASP Top 10 Proactive Controls
OWASP Top 10 Proactive ControlsOWASP Top 10 Proactive Controls
OWASP Top 10 Proactive Controls
Katy Anton
 
Spring Security
Spring SecuritySpring Security
Spring Security
Boy Tech
 
Oracle EBS Self service from A to Z
Oracle EBS Self service from A to ZOracle EBS Self service from A to Z
Oracle EBS Self service from A to Z
Feras Ahmad
 
R12:Payment Process Request (PPR)
R12:Payment Process Request (PPR)R12:Payment Process Request (PPR)
R12:Payment Process Request (PPR)
lingaswamy vallapu
 

What's hot (20)

Cyber Crime
Cyber CrimeCyber Crime
Cyber Crime
 
Security misconfiguration
Security misconfigurationSecurity misconfiguration
Security misconfiguration
 
Angular Dependency Injection
Angular Dependency InjectionAngular Dependency Injection
Angular Dependency Injection
 
Sql injection
Sql injectionSql injection
Sql injection
 
A5-Security misconfiguration-OWASP 2013
A5-Security misconfiguration-OWASP 2013   A5-Security misconfiguration-OWASP 2013
A5-Security misconfiguration-OWASP 2013
 
Dom based xss
Dom based xssDom based xss
Dom based xss
 
Boto3
Boto3Boto3
Boto3
 
Cross Site Scripting Defense Presentation
Cross Site Scripting Defense Presentation Cross Site Scripting Defense Presentation
Cross Site Scripting Defense Presentation
 
Angular Advanced Routing
Angular Advanced RoutingAngular Advanced Routing
Angular Advanced Routing
 
"15 Technique to Exploit File Upload Pages", Ebrahim Hegazy
"15 Technique to Exploit File Upload Pages", Ebrahim Hegazy"15 Technique to Exploit File Upload Pages", Ebrahim Hegazy
"15 Technique to Exploit File Upload Pages", Ebrahim Hegazy
 
Application Logging Good Bad Ugly ... Beautiful?
Application Logging Good Bad Ugly ... Beautiful?Application Logging Good Bad Ugly ... Beautiful?
Application Logging Good Bad Ugly ... Beautiful?
 
Garage4Hackers Ranchoddas Webcast Series - Bypassing Modern WAF's Exemplified...
Garage4Hackers Ranchoddas Webcast Series - Bypassing Modern WAF's Exemplified...Garage4Hackers Ranchoddas Webcast Series - Bypassing Modern WAF's Exemplified...
Garage4Hackers Ranchoddas Webcast Series - Bypassing Modern WAF's Exemplified...
 
Rest API Security
Rest API SecurityRest API Security
Rest API Security
 
9 element entry_validation_part_9
9 element entry_validation_part_99 element entry_validation_part_9
9 element entry_validation_part_9
 
OWASP Top 10 Proactive Controls
OWASP Top 10 Proactive ControlsOWASP Top 10 Proactive Controls
OWASP Top 10 Proactive Controls
 
XXE
XXEXXE
XXE
 
Spring Security
Spring SecuritySpring Security
Spring Security
 
Oracle EBS Self service from A to Z
Oracle EBS Self service from A to ZOracle EBS Self service from A to Z
Oracle EBS Self service from A to Z
 
Oracle i procurement
Oracle i procurementOracle i procurement
Oracle i procurement
 
R12:Payment Process Request (PPR)
R12:Payment Process Request (PPR)R12:Payment Process Request (PPR)
R12:Payment Process Request (PPR)
 

Viewers also liked

Why SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScriptWhy SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScriptmartinlippert
 
How Angular2 Can Improve Your AngularJS Apps Today!
How Angular2 Can Improve Your AngularJS Apps Today!How Angular2 Can Improve Your AngularJS Apps Today!
How Angular2 Can Improve Your AngularJS Apps Today!
Nir Kaufman
 
Data Structures in javaScript 2015
Data Structures in javaScript 2015Data Structures in javaScript 2015
Data Structures in javaScript 2015
Nir Kaufman
 
redux and angular - up and running
redux and angular - up and runningredux and angular - up and running
redux and angular - up and running
Nir Kaufman
 
Up & running with ECMAScript6
Up & running with ECMAScript6Up & running with ECMAScript6
Up & running with ECMAScript6
Nir Kaufman
 
Angular Pipes Workshop
Angular Pipes WorkshopAngular Pipes Workshop
Angular Pipes Workshop
Nir Kaufman
 
Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016
Nir Kaufman
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introduction
Nir Kaufman
 
Angular2 workshop
Angular2 workshopAngular2 workshop
Angular2 workshop
Nir Kaufman
 
Webstorm
WebstormWebstorm
Webstorm
Nir Kaufman
 
Angularjs - lazy loading techniques
Angularjs - lazy loading techniques Angularjs - lazy loading techniques
Angularjs - lazy loading techniques
Nir Kaufman
 
AngularJS Basics
AngularJS BasicsAngularJS Basics
AngularJS Basics
Ravi Mone
 
AngularJS Introduction
AngularJS IntroductionAngularJS Introduction
AngularJS Introduction
Carlos Morales
 
Webpack and angularjs
Webpack and angularjsWebpack and angularjs
Webpack and angularjs
Nir Kaufman
 
AngularJS - Services
AngularJS - ServicesAngularJS - Services
AngularJS - Services
Nir Kaufman
 
Solid JavaScript Coding
Solid JavaScript CodingSolid JavaScript Coding
Solid JavaScript Coding
Diwa Del Mundo
 
Angular js - 10 reasons to choose angularjs
Angular js - 10 reasons to choose angularjs Angular js - 10 reasons to choose angularjs
Angular js - 10 reasons to choose angularjs
Nir Kaufman
 
Angular redux
Angular reduxAngular redux
Angular redux
Nir Kaufman
 
Angular js routing options
Angular js routing optionsAngular js routing options
Angular js routing options
Nir Kaufman
 
Angular2 - getting-ready
Angular2 - getting-ready Angular2 - getting-ready
Angular2 - getting-ready
Nir Kaufman
 

Viewers also liked (20)

Why SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScriptWhy SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScript
 
How Angular2 Can Improve Your AngularJS Apps Today!
How Angular2 Can Improve Your AngularJS Apps Today!How Angular2 Can Improve Your AngularJS Apps Today!
How Angular2 Can Improve Your AngularJS Apps Today!
 
Data Structures in javaScript 2015
Data Structures in javaScript 2015Data Structures in javaScript 2015
Data Structures in javaScript 2015
 
redux and angular - up and running
redux and angular - up and runningredux and angular - up and running
redux and angular - up and running
 
Up & running with ECMAScript6
Up & running with ECMAScript6Up & running with ECMAScript6
Up & running with ECMAScript6
 
Angular Pipes Workshop
Angular Pipes WorkshopAngular Pipes Workshop
Angular Pipes Workshop
 
Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introduction
 
Angular2 workshop
Angular2 workshopAngular2 workshop
Angular2 workshop
 
Webstorm
WebstormWebstorm
Webstorm
 
Angularjs - lazy loading techniques
Angularjs - lazy loading techniques Angularjs - lazy loading techniques
Angularjs - lazy loading techniques
 
AngularJS Basics
AngularJS BasicsAngularJS Basics
AngularJS Basics
 
AngularJS Introduction
AngularJS IntroductionAngularJS Introduction
AngularJS Introduction
 
Webpack and angularjs
Webpack and angularjsWebpack and angularjs
Webpack and angularjs
 
AngularJS - Services
AngularJS - ServicesAngularJS - Services
AngularJS - Services
 
Solid JavaScript Coding
Solid JavaScript CodingSolid JavaScript Coding
Solid JavaScript Coding
 
Angular js - 10 reasons to choose angularjs
Angular js - 10 reasons to choose angularjs Angular js - 10 reasons to choose angularjs
Angular js - 10 reasons to choose angularjs
 
Angular redux
Angular reduxAngular redux
Angular redux
 
Angular js routing options
Angular js routing optionsAngular js routing options
Angular js routing options
 
Angular2 - getting-ready
Angular2 - getting-ready Angular2 - getting-ready
Angular2 - getting-ready
 

Similar to Solid angular

AngularJs-training
AngularJs-trainingAngularJs-training
AngularJs-training
Pratchaya Suputsopon
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"
GeeksLab Odessa
 
Building Reusable Custom Elements With Angular
Building Reusable Custom Elements With AngularBuilding Reusable Custom Elements With Angular
Building Reusable Custom Elements With Angular
Ilia Idakiev
 
Angular 2.0 forms
Angular 2.0 formsAngular 2.0 forms
Angular 2.0 forms
Eyal Vardi
 
CFUGbe talk about Angular JS
CFUGbe talk about Angular JSCFUGbe talk about Angular JS
CFUGbe talk about Angular JS
Alwyn Wymeersch
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
Omnia Helmi
 
Angular.js is super cool
Angular.js is super coolAngular.js is super cool
Angular.js is super cool
Maksym Hopei
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven Development
Nuvole
 
MVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia InstituteMVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia Institute
Ravi Bhadauria
 
Building an End-to-End AngularJS Application
Building an End-to-End AngularJS ApplicationBuilding an End-to-End AngularJS Application
Building an End-to-End AngularJS Application
Dan Wahlin
 
AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014
Ran Wahle
 
Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)
Python Ireland
 
Web Components Everywhere
Web Components EverywhereWeb Components Everywhere
Web Components Everywhere
Ilia Idakiev
 
Asp.net mvc training
Asp.net mvc trainingAsp.net mvc training
Asp.net mvc training
icubesystem
 
Embrace the Angular 2 Ethos in Angular 1.x
Embrace the Angular 2 Ethos in Angular 1.xEmbrace the Angular 2 Ethos in Angular 1.x
Embrace the Angular 2 Ethos in Angular 1.x
Lukas Ruebbelke
 
Get AngularJS Started!
Get AngularJS Started!Get AngularJS Started!
Get AngularJS Started!
Dzmitry Ivashutsin
 
MVC Training Part 2
MVC Training Part 2MVC Training Part 2
MVC Training Part 2
Lee Englestone
 

Similar to Solid angular (20)

AngularJs-training
AngularJs-trainingAngularJs-training
AngularJs-training
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"
 
Introduction to AngularJS
Introduction to AngularJSIntroduction to AngularJS
Introduction to AngularJS
 
Building Reusable Custom Elements With Angular
Building Reusable Custom Elements With AngularBuilding Reusable Custom Elements With Angular
Building Reusable Custom Elements With Angular
 
Angular 2.0 forms
Angular 2.0 formsAngular 2.0 forms
Angular 2.0 forms
 
CFUGbe talk about Angular JS
CFUGbe talk about Angular JSCFUGbe talk about Angular JS
CFUGbe talk about Angular JS
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
Angular.js is super cool
Angular.js is super coolAngular.js is super cool
Angular.js is super cool
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven Development
 
MVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia InstituteMVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia Institute
 
Backbone Basics with Examples
Backbone Basics with ExamplesBackbone Basics with Examples
Backbone Basics with Examples
 
Building an End-to-End AngularJS Application
Building an End-to-End AngularJS ApplicationBuilding an End-to-End AngularJS Application
Building an End-to-End AngularJS Application
 
AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014
 
Introduction to angular js
Introduction to angular jsIntroduction to angular js
Introduction to angular js
 
Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)
 
Web Components Everywhere
Web Components EverywhereWeb Components Everywhere
Web Components Everywhere
 
Asp.net mvc training
Asp.net mvc trainingAsp.net mvc training
Asp.net mvc training
 
Embrace the Angular 2 Ethos in Angular 1.x
Embrace the Angular 2 Ethos in Angular 1.xEmbrace the Angular 2 Ethos in Angular 1.x
Embrace the Angular 2 Ethos in Angular 1.x
 
Get AngularJS Started!
Get AngularJS Started!Get AngularJS Started!
Get AngularJS Started!
 
MVC Training Part 2
MVC Training Part 2MVC Training Part 2
MVC Training Part 2
 

More from Nir Kaufman

Angular Prestige: Less-known API and techniques
Angular Prestige: Less-known API and techniquesAngular Prestige: Less-known API and techniques
Angular Prestige: Less-known API and techniques
Nir Kaufman
 
Angular CLI custom builders
Angular CLI custom buildersAngular CLI custom builders
Angular CLI custom builders
Nir Kaufman
 
Electronic music 101 for developers
Electronic music 101 for developersElectronic music 101 for developers
Electronic music 101 for developers
Nir Kaufman
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
Nir Kaufman
 
Redux pattens - JSHeroes 2018
Redux pattens - JSHeroes 2018Redux pattens - JSHeroes 2018
Redux pattens - JSHeroes 2018
Nir Kaufman
 
Angular EE - Special Workshop by Nir Kaufman
Angular EE - Special Workshop by Nir KaufmanAngular EE - Special Workshop by Nir Kaufman
Angular EE - Special Workshop by Nir Kaufman
Nir Kaufman
 
Boosting Angular runtime performance
Boosting Angular runtime performanceBoosting Angular runtime performance
Boosting Angular runtime performance
Nir Kaufman
 
Decorators in js
Decorators in jsDecorators in js
Decorators in js
Nir Kaufman
 
Styling recipes for Angular components
Styling recipes for Angular componentsStyling recipes for Angular components
Styling recipes for Angular components
Nir Kaufman
 
Introduction To Angular's reactive forms
Introduction To Angular's reactive formsIntroduction To Angular's reactive forms
Introduction To Angular's reactive forms
Nir Kaufman
 
AngularJS performance & production tips
AngularJS performance & production tipsAngularJS performance & production tips
AngularJS performance & production tips
Nir Kaufman
 

More from Nir Kaufman (11)

Angular Prestige: Less-known API and techniques
Angular Prestige: Less-known API and techniquesAngular Prestige: Less-known API and techniques
Angular Prestige: Less-known API and techniques
 
Angular CLI custom builders
Angular CLI custom buildersAngular CLI custom builders
Angular CLI custom builders
 
Electronic music 101 for developers
Electronic music 101 for developersElectronic music 101 for developers
Electronic music 101 for developers
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
 
Redux pattens - JSHeroes 2018
Redux pattens - JSHeroes 2018Redux pattens - JSHeroes 2018
Redux pattens - JSHeroes 2018
 
Angular EE - Special Workshop by Nir Kaufman
Angular EE - Special Workshop by Nir KaufmanAngular EE - Special Workshop by Nir Kaufman
Angular EE - Special Workshop by Nir Kaufman
 
Boosting Angular runtime performance
Boosting Angular runtime performanceBoosting Angular runtime performance
Boosting Angular runtime performance
 
Decorators in js
Decorators in jsDecorators in js
Decorators in js
 
Styling recipes for Angular components
Styling recipes for Angular componentsStyling recipes for Angular components
Styling recipes for Angular components
 
Introduction To Angular's reactive forms
Introduction To Angular's reactive formsIntroduction To Angular's reactive forms
Introduction To Angular's reactive forms
 
AngularJS performance & production tips
AngularJS performance & production tipsAngularJS performance & production tips
AngularJS performance & production tips
 

Recently uploaded

FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
Bhaskar Mitra
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
CatarinaPereira64715
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 

Recently uploaded (20)

FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 

Solid angular

  • 1. HOW ANGULAR CAN SOLVE ALL YOUR PROBLEMS Nir Kaufman
  • 3. Nir Kaufman - I don’t really need glasses to see - This photo is a photoshop - In reality I’m in color (and fatter) Head of AngularJS Development @ 500Tech
  • 5. “We are not happy with our app. it should be modular, easy to extend and maintain. It’s hard to understand the flow, feels like a spaghetti of presentation and business logic. - frontend team at {{ company.name }}
  • 6. WE NEED A BETTER FRAMEWORK
  • 7.
  • 8.
  • 9. WHAT DO WE NEED?
  • 11. A clean way of organizing your UI code into self-contained, reusable chunks
  • 12. // component controller
 class likeBoxController {
 
 constructor(params) {
 this.chosenValue = params.value;
 }
 
 like() {
 this.chosenValue('like');
 }
 
 dislike() {
 this.chosenValue('dislike');
 }
 }
 
 // component definition
 function likeBoxComponent() {
 return {
 viewModel: likeBoxController,
 template: likeBoxTemplate
 }
 }
 
 // component registration
 ko.components.register('like-widget', likeBoxComponent());
  • 13. // component controller
 class likeBoxController {
 
 constructor() {
 this.chosenValue = null;
 }
 
 like() {
 this.chosenValue = 'like';
 }
 
 dislike() {
 this.chosenValue = 'dislike';
 }
 }
 
 // component definition
 function likeBoxComponent() {
 return {
 controller: likeBoxController,
 scope: { params: ‘=chosenValue' },
 controllerAs: 'LikeBox',
 bindToController: true,
 template: likeBoxTemplate
 }
 }
 
 angular.module('app', [])
 .directive('likeWidget', likeBoxComponent);
  • 14. <div class="like-or-dislike" data-bind="visible: !chosenValue()">
 <button data-bind="click: like">Like it</button>
 <button data-bind="click: dislike">Dislike it</button>
 </div>
 
 <div class="result" data-bind="visible: chosenValue">
 You <strong data-bind="text: chosenValue"></strong> it
 </div> <div class="like-or-dislike" ng-hide="LikeBox.chosenValue">
 <button ng-click="LikeBox.like()">Like it</button>
 <button ng-click="LikeBox.dislike()">Dislike it</button>
 </div>
 
 <div class="result" ng-show="LikeBox.chosenValue">
 You <strong ng-bind="LikeBox.chosenValue"></strong> it
 </div>

  • 15. class LikeWidget extends React.Component {
 
 constructor(props) {
 super(props);
 
 this.state = { chosenValue: null };
 
 this.like = this.like.bind(this);
 this.dislike = this.dislike.bind(this);
 this._likeButtons = this._likeButtons.bind(this)
 }
 
 like() {
 this.setState({
 chosenValue: 'like'
 })
 }
 
 dislike() {
 this.setState({
 chosenValue: 'dislike'
 })
 }
 
 
 _likeButtons() {
 if (this.state.chosenValue) {
 return null
 }
 
 return (
 <div>
 <button onClick={this.like}>Like it</button>
 <button onClick={this.dislike}>Dislike it</button>
 </div>
 )
 }
 
 render() {
 return (
 <div>
 { this._likeButtons() }
 { this.state.chosenValue ?
 <div>You <strong>{ this.state.chosenValue }</strong> it </div> : null}
 </div>
 )
 }
 }
 
 React.render(<LikeWidget/>, document.getElementById('app'));
  • 17. Keep your business logic separate from your user interface
  • 18. class MyViewModel {
 
 constructor() {
 this.products = [
 new Product('Garlic bread'),
 new Product('Pain au chocolat'),
 new Product('Seagull spaghetti', 'like')
 ];
 }
 }
 
 ko.applyBindings(new MyViewModel()); class MyViewModel {
 
 constructor() {
 this.products = [
 new Product('Garlic bread'),
 new Product('Pain au chocolat'),
 new Product('Seagull spaghetti', 'like')
 ];
 }
 }
 
 angular.module('app', [])
 .controller('MyViewModel', MyViewModel);
  • 19. Backbone.Model.extend({
 defaults: {
 coverImage: 'img/placeholder.png',
 title: 'No title',
 author: 'Unknown',
 releaseDate: 'Unknown',
 keywords: 'None'
 }
 }); DS.Model.extend({
 title: DS.attr('No title'),
 author: DS.attr('Unknown'),
 releaseDate: DS.attr('Unknown'),
 keywords: DS.attr('None')
 }); class Book {
 constructor() {
 this.coverImage = 'img/placeholder.png';
 this.title = 'No title';
 this.author = 'Unknown';
 this.releaseDate = 'Unknown';
 this.keywords = 'None';
 }
 }
  • 20. LETS GET TO THE POINT
  • 21. All major frameworks introduce the same concepts. Don’t make a switch for the wrong reasons. Switching to another framework won’t solve your design problems.
  • 23. CONSIDER TYPESCRIPT I used to hate it…
  • 24. SOLID PRINCIPLES Single Responsibility Open / Closed Liskov Substitution Interface Segregation Dependency Inversion
  • 26. A module should have one, and only one reason to change
  • 27. // module declarations
 angular.module('app', [
 'ui.router',
 'LocalStorageModule',
 'app.states'
 ])
 .config(($stateProvider, $httpProvider, localStorageServiceProvider) => {
 
 // start routing
 $stateProvider
 .state('dashboard', {
 url: '/dashboard',
 templateUrl: 'states/dashboard/dashboard.html',
 controller: 'DashboardController'
 })
 
 .state('users', {
 url: '/users',
 templateUrl: 'states/users/users.html',
 controller: 'UsersController'
 });
 
 // http configuration
 $httpProvider.useApplyAsync(true);
 $httpProvider.useLegacyPromiseExtensions(false);
 
 $httpProvider.interceptors.push(($log) => {
 return {
 'request': function (config) {
 $log.debug(config);
 return config;
 }
 };
 });
 
 // storage configurations
 localStorageServiceProvider
 .setPrefix('myApp')
 .setStorageType('sessionStorage')
 });
 
 // start engines
 angular.bootstrap(document, ['app']); 4 reasons to change this module: add dependency add new state configure http service configure storage service
  • 28. // module declarations
 angular.module('app', [
 'ui.router',
 'LocalStorageModule',
 'app.states'
 ])
 .config(routes)
 .config(http)
 .config(storage)
 
 // start engines
 angular.bootstrap(document, ['app']); export function routes($stateProvider) {
 $stateProvider
 .state('dashboard', {
 url: '/dashboard',
 templateUrl: 'states/dashboard/dashboard.html',
 controller: 'DashboardController'
 })
 
 .state('users', {
 url: '/users',
 templateUrl: 'states/users/users.html',
 controller: 'UsersController'
 });
 }
 routes.ts app.ts export function http ($httpProvider) {
 $httpProvider.useApplyAsync(true);
 $httpProvider.useLegacyPromiseExtensions(false);
 } http.ts export function storage(localStorageServiceProvider) {
 localStorageServiceProvider
 .setPrefix('myApp')
 .setStorageType('sessionStorage')
 } storage.ts
  • 29. // module declarations
 angular.module('app', [
 'ui.router',
 'LocalStorageModule',
 'app.states'
 ])
 .config(routes)
 .config(http)
 .config(storage)
 
 // start engines
 angular.bootstrap(document, ['app']); Are we there yet? 2 reasons to change // module declarations
 angular.module('app', [
 'ui.router',
 'LocalStorageModule',
 'app.states'
 ])
 // start engines
 angular.bootstrap(document, ['app']); 1 responsibility
  • 31. A module should be open for extension, but closed for modification.
  • 32. class Modal {
 
 constructor($modal) {
 this.modal = $modal;
 }
 
 show(type) {
 
 switch (type) {
 case 'login':
 this.showLoginModal();
 break;
 case 'info':
 this.showInfoModal();
 break;
 }
 }
 
 showLoginModal() {
 this.modal.open({
 template: 'loginModal.html',
 controller: ‘loginModalController’
 })
 }
 
 showInfoModal() {
 this.modal.open({
 template: 'infoModal.html',
 controller: 'infoModalController'
 })
 }
 } class Controller {
 
 constructor(Modal) {
 this.Modal = Modal;
 }
 
 showLogin(){
 this.Modal.show('login');
 }
 } We need to add new Modals to our system
  • 33. class Modal {
 
 constructor($modal) {
 this.modal = $modal;
 this.modals = new Map();
 }
 
 register(type, config) {
 this.modals.set(type, config)
 }
 
 $get() {
 return { show: this.show }
 }
 
 show(type) {
 if(this.modals.has(type)){
 this.modal.open(this.modals.get(type))
 }
 }
 }
 angular.module('app', [])
 .config(ModalProvider => {
 
 ModalProvider.register('lostPassword', {
 template: 'lostPassword.html',
 controller: 'lostPasswordController'
 })
 }); class Controller {
 
 constructor(Modal) {
 this.Modal = Modal;
 }
 
 showLogin(){
 this.Modal.show('lostPassword');
 }
 } Write code that can be extended
  • 35. Child classes should never break the parent class type definitions
  • 39. Many specific interfaces are better than one generic interface
  • 40. I just want to make a copy
  • 41. class LocalStorage {
 private storage;
 private $window;
 
 constructor($window, $q) {
 this.$window = $window;
 }
 
 setStorageType(type:string) {
 if (type === 'local') {
 return this.storage = this.$window.localStorage;
 }
 if (type === 'db') {
 return this.storage = new PouchDB('DB');
 }
 }
 
 setLocalItem(key:string, data) {
 if (this.db) {
 return this.db.put(JSON.parse(data))
 }
 return this.storage.setItem(key, JSON.stringify(data));
 } put(data) {
 this.storage.put(JSON.parse(data))
 } 
 getLocalItem(key:string):string {
 let deferred = this.$q.defer();
 
 if (this.db) {
 this.db.get(key).then( result => deferred.resolve() )
 }
 deferred.resolve(this.storage.getItem());
 return deferred.promise;
 }
 } No client should be forced to depend on methods it doesn’t use
  • 42. class LocalStorage {
 private storage;
 
 constructor($window) {
 this.storage = $window.localStorage;
 }
 
 
 setItem(key:string, data) {
 return this.storage.setItem(key, JSON.stringify(data));
 }
 
 getItem(key:string):string {
 return this.storage.getItem();
 }
 } class SessionStorage {
 private storage;
 
 constructor($window, $q) {
 this.storage = $window.sessionStorage;
 }
 
 setItem(key:string, data) {
 return this.storage.setItem(key, JSON.stringify(data));
 }
 
 getItem(key:string):string {
 return this.storage.getItem();
 }
 } localStorage.ts sessionStorage.ts class DBStorage {
 private db;
 
 constructor(PouchDB) {
 this.db = new PouchDB('DB');
 }
 
 put(data) {
 this.db.put(data)
 }
 
 get(id){
 return this.db.get(id);
 }
 } dbStorage.ts UserComponent.ts (client) class UserComponent {
 private storage;
 
 constructor(LocalStorage) {
 this.storage = LocalStorage
 }
 }
  • 44. High-level modules should not depend on low-level modules. Both should depend on abstractions.
  • 45. NATIVE API’s ANGULAR 3RD PARTY MODULES APLLICATION CODE INTERFACES Application Layers YOUR MODULES Abstraction Abstraction
  • 46. interface IStorage {
 setItem(key:string, data:any);
 getItem(key:string, data:any);
 } IStorgae.ts UserComponent.ts (client) class UserComponent {
 private storage;
 
 constructor(Storage: IStorage) {
 this.storage = LocalStorage
 }
 } LocalStorage.ts class LocalStorage implements IStorage {
 private storage;
 
 constructor($window) {
 this.storage = $window.localStorage;
 }
 
 setItem(key:string, data) {
 return this.storage.setItem(key, JSON.stringify(data));
 }
 
 getItem(key:string):string {
 return this.storage.getItem();
 }
 } The ‘client’ can work with any kind of storage that implements the IStorage interface
  • 47. export class WelcomeController {
 
 constructor($modal) {
 this.$modal = $modal;
 }
 
 login() {
 let loginModalInstance = this.$modal.open({
 templateUrl: 'states/welcome/login_modal.html',
 keyboard: false,
 backdrop: 'static',
 controller: LoginModalController,
 controllerAs: 'Login'
 });
 
 loginModalInstance.result
 .then(result => console.log(result))
 }
 } Angular Bootstrap Modal export class DashboardController {
 
 constructor($modal) {
 this.$modal = $modal;
 }
 
 showInfo() {
 let infoModalInstance = this.$modal.open({
 templateUrl: 'states/dashboard/info_modal.html',
 keyboard: false,
 backdrop: 'static',
 controller: InfoModalController,
 controllerAs: 'Info'
 });
 
 infoModalInstance.result
 .then(result => console.log(result))
 }
 } What is the problem?
  • 48. class Modal {
 
 constructor($modal) {
 this.modal = $modal;
 this.modals = new Map();
 }
 
 register(type, config) {
 this.modals.set(type, config)
 }
 
 $get() {
 return { show: this.show }
 }
 
 show(type) {
 if(this.modals.has(type)){
 this.modal.open(this.modals.get(type))
 }
 }
 }
 Abstraction without TypeScript
  • 50. DON’T MAKE A SWITCH FOR THE WRONG REASONS
  • 54. Angular ES6 / TypeScript Starters https://github.com/nirkaufman/angular-webpack-starter https://github.com/nirkaufman/angular-webpack-typescript-starter