SlideShare une entreprise Scribd logo
1  sur  56
Télécharger pour lire hors ligne
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

Contenu connexe

Tendances

Demystifying Angular Animations
Demystifying Angular AnimationsDemystifying Angular Animations
Demystifying Angular AnimationsGil Fink
 
Solid NodeJS with TypeScript, Jest & NestJS
Solid NodeJS with TypeScript, Jest & NestJSSolid NodeJS with TypeScript, Jest & NestJS
Solid NodeJS with TypeScript, Jest & NestJSRafael Casuso Romate
 
MVVM ( Model View ViewModel )
MVVM ( Model View ViewModel )MVVM ( Model View ViewModel )
MVVM ( Model View ViewModel )Ahmed Emad
 
Angular - Chapter 2 - TypeScript Programming
Angular - Chapter 2 - TypeScript Programming  Angular - Chapter 2 - TypeScript Programming
Angular - Chapter 2 - TypeScript Programming WebStackAcademy
 
How to implement internationalization (i18n) in angular application(multiple ...
How to implement internationalization (i18n) in angular application(multiple ...How to implement internationalization (i18n) in angular application(multiple ...
How to implement internationalization (i18n) in angular application(multiple ...Katy Slemon
 
Best Practices NgRx for Scaling Your Angular Application
Best Practices NgRx  for Scaling Your Angular ApplicationBest Practices NgRx  for Scaling Your Angular Application
Best Practices NgRx for Scaling Your Angular ApplicationVagner Oliveira
 
Design principles - SOLID
Design principles - SOLIDDesign principles - SOLID
Design principles - SOLIDPranalee Rokde
 
Clean code: SOLID (iOS)
Clean code: SOLID (iOS)Clean code: SOLID (iOS)
Clean code: SOLID (iOS)Maksym Husar
 
Is it time to migrate to Vue 3?
Is it time to migrate to Vue 3?Is it time to migrate to Vue 3?
Is it time to migrate to Vue 3?Denny Biasiolli
 
Angular Routing Guard
Angular Routing GuardAngular Routing Guard
Angular Routing GuardKnoldus Inc.
 
Introduction to Google Guice
Introduction to Google GuiceIntroduction to Google Guice
Introduction to Google GuiceKnoldus Inc.
 
SQL Injections - A Powerpoint Presentation
SQL Injections - A Powerpoint PresentationSQL Injections - A Powerpoint Presentation
SQL Injections - A Powerpoint PresentationRapid Purple
 
Java Database Connectivity
Java Database ConnectivityJava Database Connectivity
Java Database Connectivitybackdoor
 
Angular interview questions
Angular interview questionsAngular interview questions
Angular interview questionsGoa App
 

Tendances (20)

Demystifying Angular Animations
Demystifying Angular AnimationsDemystifying Angular Animations
Demystifying Angular Animations
 
Solid NodeJS with TypeScript, Jest & NestJS
Solid NodeJS with TypeScript, Jest & NestJSSolid NodeJS with TypeScript, Jest & NestJS
Solid NodeJS with TypeScript, Jest & NestJS
 
MVVM ( Model View ViewModel )
MVVM ( Model View ViewModel )MVVM ( Model View ViewModel )
MVVM ( Model View ViewModel )
 
Google Guice
Google GuiceGoogle Guice
Google Guice
 
Angular - Chapter 2 - TypeScript Programming
Angular - Chapter 2 - TypeScript Programming  Angular - Chapter 2 - TypeScript Programming
Angular - Chapter 2 - TypeScript Programming
 
Solid principles
Solid principlesSolid principles
Solid principles
 
How to implement internationalization (i18n) in angular application(multiple ...
How to implement internationalization (i18n) in angular application(multiple ...How to implement internationalization (i18n) in angular application(multiple ...
How to implement internationalization (i18n) in angular application(multiple ...
 
Best Practices NgRx for Scaling Your Angular Application
Best Practices NgRx  for Scaling Your Angular ApplicationBest Practices NgRx  for Scaling Your Angular Application
Best Practices NgRx for Scaling Your Angular Application
 
Angular 9
Angular 9 Angular 9
Angular 9
 
Design principles - SOLID
Design principles - SOLIDDesign principles - SOLID
Design principles - SOLID
 
Clean code: SOLID (iOS)
Clean code: SOLID (iOS)Clean code: SOLID (iOS)
Clean code: SOLID (iOS)
 
Is it time to migrate to Vue 3?
Is it time to migrate to Vue 3?Is it time to migrate to Vue 3?
Is it time to migrate to Vue 3?
 
Android MVVM
Android MVVMAndroid MVVM
Android MVVM
 
Learning Svelte
Learning SvelteLearning Svelte
Learning Svelte
 
Angular Routing Guard
Angular Routing GuardAngular Routing Guard
Angular Routing Guard
 
Introduction to Google Guice
Introduction to Google GuiceIntroduction to Google Guice
Introduction to Google Guice
 
Basics of VueJS
Basics of VueJSBasics of VueJS
Basics of VueJS
 
SQL Injections - A Powerpoint Presentation
SQL Injections - A Powerpoint PresentationSQL Injections - A Powerpoint Presentation
SQL Injections - A Powerpoint Presentation
 
Java Database Connectivity
Java Database ConnectivityJava Database Connectivity
Java Database Connectivity
 
Angular interview questions
Angular interview questionsAngular interview questions
Angular interview questions
 

En vedette

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 2015Nir Kaufman
 
redux and angular - up and running
redux and angular - up and runningredux and angular - up and running
redux and angular - up and runningNir Kaufman
 
Up & running with ECMAScript6
Up & running with ECMAScript6Up & running with ECMAScript6
Up & running with ECMAScript6Nir Kaufman
 
Angular Pipes Workshop
Angular Pipes WorkshopAngular Pipes Workshop
Angular Pipes WorkshopNir Kaufman
 
Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Nir Kaufman
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introductionNir Kaufman
 
Angular2 workshop
Angular2 workshopAngular2 workshop
Angular2 workshopNir 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 BasicsRavi Mone
 
AngularJS Introduction
AngularJS IntroductionAngularJS Introduction
AngularJS IntroductionCarlos Morales
 
Webpack and angularjs
Webpack and angularjsWebpack and angularjs
Webpack and angularjsNir Kaufman
 
AngularJS - Services
AngularJS - ServicesAngularJS - Services
AngularJS - ServicesNir Kaufman
 
Solid JavaScript Coding
Solid JavaScript CodingSolid JavaScript Coding
Solid JavaScript CodingDiwa 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 js routing options
Angular js routing optionsAngular js routing options
Angular js routing optionsNir Kaufman
 
Angular2 - getting-ready
Angular2 - getting-ready Angular2 - getting-ready
Angular2 - getting-ready Nir Kaufman
 

En vedette (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
 

Similaire à Solid angular

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 AngularIlia Idakiev
 
Angular 2.0 forms
Angular 2.0 formsAngular 2.0 forms
Angular 2.0 formsEyal Vardi
 
CFUGbe talk about Angular JS
CFUGbe talk about Angular JSCFUGbe talk about Angular JS
CFUGbe talk about Angular JSAlwyn Wymeersch
 
Angular.js is super cool
Angular.js is super coolAngular.js is super cool
Angular.js is super coolMaksym 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 DevelopmentNuvole
 
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 InstituteRavi 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 ApplicationDan Wahlin
 
AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014Ran 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 EverywhereIlia Idakiev
 
Asp.net mvc training
Asp.net mvc trainingAsp.net mvc training
Asp.net mvc trainingicubesystem
 
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.xLukas Ruebbelke
 

Similaire à 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
 

Plus de 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 techniquesNir Kaufman
 
Angular CLI custom builders
Angular CLI custom buildersAngular CLI custom builders
Angular CLI custom buildersNir Kaufman
 
Electronic music 101 for developers
Electronic music 101 for developersElectronic music 101 for developers
Electronic music 101 for developersNir Kaufman
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass SlidesNir Kaufman
 
Redux pattens - JSHeroes 2018
Redux pattens - JSHeroes 2018Redux pattens - JSHeroes 2018
Redux pattens - JSHeroes 2018Nir 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 KaufmanNir Kaufman
 
Boosting Angular runtime performance
Boosting Angular runtime performanceBoosting Angular runtime performance
Boosting Angular runtime performanceNir Kaufman
 
Decorators in js
Decorators in jsDecorators in js
Decorators in jsNir Kaufman
 
Styling recipes for Angular components
Styling recipes for Angular componentsStyling recipes for Angular components
Styling recipes for Angular componentsNir Kaufman
 
Introduction To Angular's reactive forms
Introduction To Angular's reactive formsIntroduction To Angular's reactive forms
Introduction To Angular's reactive formsNir Kaufman
 
AngularJS performance & production tips
AngularJS performance & production tipsAngularJS performance & production tips
AngularJS performance & production tipsNir Kaufman
 

Plus de 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
 

Dernier

Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityWSO2
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Zilliz
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)Samir Dash
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 

Dernier (20)

Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 

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