SlideShare a Scribd company logo
1 of 77
Download to read offline
FRONT MVC
@DRPICOX
THINGS WRONG THAT I DID TO FIT THINGS IN SLIDES
DISCLAIMER
• Directives should use controller and bindToController
• Directives should never load resources, this should be done by
routes or under demand
• Use .factory to simplify and homogenize code

(not .service neither .value)
• In a previous talk I said that model was plain JS data, sorry 

(plain data is the form, but does not defines a model)
• Use better variable names
MVC - MODEL THE
GREAT FORGOTTEN
FRONT MVC
TYPICAL ANGULAR CODE
AS SEEN ON SOME DOCS
(AND FROM SOME BEGINNERS)
TYPICAL ANGULAR CODE
<APP-BOOKS-LIST>
app.component(‘appBooksList’, {
template: ‘…’,
controller($http) {
$http.get(‘/api/v1/books’).then(response => {
this.books = response.data;
});
},
});
TYPICAL ANGULAR CODE
<APP-SCI-FI-BOOKS-LIST>
app.component(‘appSciFiBooksList’, {
template: ‘…’,
controller($http) {
$http.get(‘/api/v1/books’).then(response => {
this.books = response.data.filter(isSciFi);
});
},
});
REFACTORING - SERVICE
THERE IS REPLICATED CODE
¡LET’S DO A SERVICE!
REFACTORING - SERVICE
booksService
app.service(‘booksService’, ($http) => {
this.getList = () => {
return $http.get(‘/api/v1/books’).then(function(response) {
return response.data;
});
};
});
Acquires the responsibility for:
• R1: Know the API context Url
• R2: Create a remote connection
• R3: Transform response into usable object
REFACTORING - SERVICE
<APP-BOOKS-LIST> & <APP-SCI-FI-BOOKS-LIST>
app.component(‘appBooksList’, {
template: ‘…’,
controller(booksService) {
booksService.getList().then(books => {
this.books = books;
});
},
});
app.component(‘appSciFiBooksList’, {
template: ‘…’,
controller(booksService) {
booksService.getList().then(books => {
this.books = books.filter(isSciFi);
});
},
});
PERFORMANCE - CACHING
OPS! WE ARE LOADING DATA TWICE
¡LET’S DO A CACHE!
PERFORMANCE - CACHING
booksService
Notice that:
• Repairs all directives at once
• Acquires one new responsibility (R4: manage cache)
app.service(‘booksService’, ($http) => {
this.getList = () => {
return $http.get(‘/api/v1/books’, {cache:true}).then(response => {
return response.data;
});
};
});
PERFORMANCE - CACHING
booksService
Notice that:
• Repairs all directives at once
• Acquires one new responsibility (R4: manage cache)
app.service(‘booksService’, ($http) => {
this.getList = () => {
if (!this.list) {
this.list = $http.get(‘/api/v1/books’).then(response => {
return response.data;
});
}
return this.list;
};
});
Alternate
NEW FEATURE - ONE BOOK
WE HAVE A VIEW THAT ONLY SHOWS ONE BOOK
NEW FEATURE - ONE BOOK
<APP-BOOK-VIEW BOOK-ID=“ID”>
app.component(‘appBookView’, {
template: ‘…’,
bindings: { bookId: ‘<‘ },
controller: function(booksService) {
booksService.get(this.bookId).then(book => { this.book = book; });
},
});
NEW FEATURE - ONE BOOK
booksService (step1)
Notice that:
• What about repeating loading of books (R4: manage cache)
app.service(‘booksService’, ($http) => {
this.loadAll = function() {
return $http.get(‘/api/v1/books’, {cache:true}).then(response => {
return response.data;
});
};
this.load = (id) => {
return $http.get(‘/api/v1/books/’+id).then(response => {
return response.data;
});
};
});
NEW FEATURE - ONE BOOK
booksService (step2)
• Uhmmmm… about R4… managing caches
app.service(‘booksService’, ($http) => {
this.loadAll = function() {
return $http.get(‘/api/v1/books’, {cache:true}).then(response => {
return response.data;
});
};
this.load = (id) => {
return $http.get(‘/api/v1/books/’+id, {cache:true}).then(response => {
return response.data;
});
};
});
NEW FEATURE - ONE BOOK
WE ARE LOADING TWICE THE SAME BOOK!
It happens when:
• Loading one book
• Loading all books
NEW FEATURE - ONE BOOK
OK… MAY BE IT’S OK LOAD TWICE
BUT NOT MORE TIMES
THE SAME BOOK
“We keep it simple…”
NEW FEATURE - UPDATE BOOK
WE HAVE A VIEW THAT MAKES AN UPDATE OF A BOOK
AND SHOWS THE CHANGES INTRODUCED BY API
NEW FEATURE - UPDATE BOOK
<APP-BOOK-UPDATE BOOK-ID=“ID”>
app.component(‘appBookUpdate’, {
template: ‘…’,
bindings: { bookId: ‘<‘, }
constructor(booksService) {
booksService.load(this).then(book => {
this.book = book;
});
this.update = () => {
booksService.update(this.book).then(updatedBook => {
this.book = updatedBook;
});
};
};
});
NEW FEATURE - ONE BOOK
booksService (step2)
• Uhmmmm… about R4… managing caches
app.service(‘booksService’, ($http) => {
this.getList = () => {
return $http.get(‘/api/v1/books’, {cache:true}).then(response => {
return response.data;
});
};
this.get = (id) => {
return $http.get(‘/api/v1/books/’+id, {cache:true})
.then(response => { return response.data; });
};
this.update = (book) => {
return $http.put(‘/api/v1/books/’+book.id)
.then(function(response) { return response.data; });
};
});
NEW FEATURE - UPDATE BOOK
SHIT!
NEW FEATURE - UPDATE BOOK
SHIT!
What about:
• Cache?
• What if we have a list side-by side, it is updated?
• What if we have view and update side-by-side?
NEW FEATURE - UPDATE BOOK
SHIT!
How to solve it?
• New services?
• Callbacks?
• RxJS?
• More caches?
• Events?
NEW FEATURE - UPDATE BOOK
WHAT IS THE REAL PROBLEM?
NEW FEATURE - UPDATE BOOK
WHAT IS THE REAL PROBLEM?
R4 (manage caches) is hidden another responsibility:
• Single source of true
We need a model!
WHAT A MODEL IS NOT?
• A model is not styles in the web
• A model is not objects in the scope
• A model is not objects stored in the browser (local,websql,…)
• A model are not instances of any sort of data
• A model is not plain data
SINGLE SOURCE OF TRUE
WHAT IS A MODEL?
• You can find your model
• There is only one instance for each “concept”

(all books with the same id are the same object)
• Models may be computed from other models
• It does not matters how many views do you have, 

all views use the same models

(as do services also)
That is something that ember programmers knows very well.
REFACTOR - ADD MODEL
Book
app.value(‘Book’, function Book(id) {
this.id = id;
this.isSciFi = function() { return !!this.tags.sciFi; };
this.takeData = function(bookData) {
angular.extend(this, bookData);
};
});
We discover new responsibilities:
• R5: update and extract information of a book
REFACTOR - ADD MODEL
booksDictionary
app.value(‘booksDictionary’, (Book) => {
this.list = []; this.map = {};
this.getOrCreate = (id) => {
var book = this.map[id];
if (!book) {
book = new Book(id);
this.list.push(book); this.list.map[id] = book;
};
return book;
};
this.takeDatas = (bookDatas) => {
bookInfos.forEach((bookData) => {
this.getOrCreate(bookData.id).takeData(bookData);
});
};
});
We discover new responsibilities:
• R6: manage book instances to avoid replicates
• R7: store books so anyone can access to them
Note that list

is also a model.
booksService (loadAll)
app.service(‘booksService’, (booksDictionary, $http) => {
this.getList = () => {
if (!this.list) {
this.list = $http.get(‘/api/v1/books’).then(response => {
booksDictionary.takeDatas(response.data);
return booksDictionary.list;
});
}
return this.list;
});
};
…
});
REFACTOR - ADD MODEL
getList returns always the same instance of list.
booksService (load)
app.service(‘booksService’, (booksDictionary, $http) => {
…
this.books = {};
this.load = (id) => {
if (!this.books[id]) {
this.books[id] = $http.get(‘/api/v1/books/’+id).then(response => {
var book = booksDictionary.getOrCreate(id);
book.takeData(reponse.data);
return book;
});
}
return this.books[id];
};
…
});
REFACTOR - ADD MODEL
Load(id) returns always the same instance of book for the same id.
And the instance will be contained by the list in getList.
booksService (update)
app.service(‘booksService’, (booksDictionary, $http) => {
…
this.update = (book) => {
var id = book.id;
this.books[id] = $http.put(‘/api/v1/books/’+id).then(response => {
var book = booksDictionary.getOrCreate(id);
book.takeData(response.data);
return book;
});
};
});
REFACTOR - ADD MODEL
Update returns always the same instance than get and getList,
regardless the input. And also updates the same instance.
three layers
REFACTOR - ADD MODEL
SERVICES
MODELS VIEWS
calls
updates
are $watched
NEW FEATURE - UPDATE BOOK
DONE!
NEW FEATURE - UPDATE BOOK
DONE?
What about Sci-Fi list?
• Is computed:

it has to be recomputed each time that a book o list changes

• A filter is expensive
• Watch a derive function is expensive
• Watch all books (aka $watch(,,true)) is expensive
NEW FEATURE - UPDATE BOOK
SHIT!
Solved in the next talk…
MVS: MVC IN
ANGULAR
FRONT MVC
three kinds of components
ORIGINAL MVC
CONTROLLERS
MODELS VIEWS
are listenedupdates
are observed
the truth
ORIGINAL MVC
MODELS VIEWS
knows and queries
are listenedupdates
are observed
knows and queries
CONTROLLERS
ORIGINAL MVC
SHIT!
ORIGINAL MVC
SHIT!
It is not as beautiful and easy as it seems.
May be it worked in ’78, with just few Kb…
and low complexity, but now…
FB comments about MVC
ARCHITECTURES VARIATIONS
https://youtu.be/nYkdrAPrdcw?t=10m20s
FB comments about MVC
ARCHITECTURES VARIATIONS
“MVC works pretty well
for small applications…
but it doesn’t make room
for new features.”
“Flux is a single direction data flow,
that avoids all the arrows
going on all directions
what makes really
hard to understand the system.”
FB comments about MVC
ARCHITECTURES VARIATIONS
“Let’s see a real good example: FB chat”
“How we get to the point, so we were annoying our
users so much the just they wanted us to fix chat?”
“The problems here were:
• The code has no structure
• It was very imperative, that makes it fragile
• It loose a lot of the original intend behind it, its hard to tell what it tries [to do]
• Add more features only gets this code larger
• We had our most annoying chat bug happen over and over
• We were always fixing some pretty good edge case, the whole system was fragile
• …
• This code becomes more fragile with the time.
• No member of the team wanted to touch it, they wanted to jump to any other bug.”
flux
ARCHITECTURES VARIATIONS
AND COMMUNITY ALSO CONTRIBUTED…
ARCHITECTURES VARIATIONS
redux
ARCHITECTURES VARIATIONS
cyclejs
ARCHITECTURES VARIATIONS
Key points are:
• Single direction flow
• Avoid imperative code
• Decoupled state from views
• Computed data consistency

(example: cart.price = ∑item.price * item.quantity)
ARCHITECTURES VARIATIONS
mvc
FROM MVC TO MVS
MODELS VIEWS
knows and queries
are listenedupdates
are observed
knows and queries
CONTROLLERS
mvc-angular
FROM MVC TO MVS
MODELS VIEWS
knows and queries
are $watched
CONTR
OLLERS
the same flow
FROM MVC TO MVS
SERVICES
MODELS VIEWS
calls
updates
are $watched
MVS RULES (I)
SERVICES
MODELS VIEWS
calls
updates
are $watched
• Views can call to services
• Services manages models
• Models are watched by views through $watch
• Views cannot modify models but temporary copies
• Each services has its own models and do not modify other
services models
Key points are:
• Single direction flow
• Avoid imperative code
• Decoupled state from views
• Computed data consistency

(example: sciFiBooks = books.filter(isSciFi))
ANGULAR MVS
SOLUTION FOR SCI-FI-BOOKS
• Create a new model for SciFiBooks
• Add a method getSciFiBooks() to bookService
• Recompute the list each time that an update() method is called
BUT!
SOLUTION FOR SCI-FI-BOOKS
BUT!
It does not scale.
¿What happens with more kind of books?
¿What happens with more complex data?
SOLUTION FOR SCI-FI-BOOKS
SOLUTION FOR SCI-FI-BOOKS
• We need a synchronization mechanism
• ex: events or observables
SOLUTION FOR COMPUTED VALUES
MODELS
• Models launch update: ex $broadcast(‘booksChanged’)
for angular1
fire events
SOLUTION FOR COMPUTED VALUES
MODELS
• Models launch update: ex $broadcast(‘booksChanged’)





• Rules:
• Each model has its own event (1 <-> 1)
• We do not pass any information (ex: previous and new value)
• Change event is fired by the Service that manages the model
• Events can be debounced (multiple collapsed in one)
rules
fire events
booksService (update)
app.service(‘booksService’, (booksDictionary, $http, $broadcast) => {
…
this.update = (book) => {
var id = book.id;
this.books[id] = $http.put(‘/api/v1/books/’+id).then(response => {
var book = booksDictionary.getOrCreate(id);
book.takeData(response.data);
$broadcast(‘booksChanged’);
return book;
});
};
});
SOLUTION FOR SCI-FI-BOOKS
<APP-SCI-FI-BOOKS-LIST> (update)
SOLUTION FOR SCI-FI-BOOKS
app.component(‘appSciFiBooksList’, {
template: ‘…’,
controller(booksService, $scope) {
getSciFiBooks();
$scope.$on(‘booksChanged’, getSciFiBooks);
function getSciFiBooks() {
booksService.getList().then(books => {
this.books = books.filter(isSciFi);
});
}
},
});
<APP-SCI-FI-BOOKS-LIST> (update)
SOLUTION FOR SCI-FI-BOOKS
app.component(‘appSciFiBooksList’, {
template: ‘…’,
controller(booksService, $scope) {
getSciFiBooks();
$scope.$on(‘booksChanged’, getSciFiBooks);
function getSciFiBooks() {
booksService.getList().then(books => {
this.books = books.filter(isSciFi);
});
}
},
});
It smells to a service function…
sciFiBooksService (update)
app.service(‘sciFiBooksService’, (booksService, $rootScope) => {
this.list = [];
this.getList = () => this.list;
updateList();
$rootScope.$on(‘booksChanged’, updateList);
function updateList() {
booksService.getList().then(books => {
angular.copy(books.filter(isSciFi), this.list);
$broadcast(‘sciFiChanged’);
});
}
});
SOLUTION FOR SCI-FI-BOOKS
<APP-SCI-FI-BOOKS-LIST> (update)
SOLUTION FOR SCI-FI-BOOKS
app.component(‘appSciFiBooksList’, {
template: ‘…’,
controller(sciFiBooksService, $scope) {
sciFiBooksService.getList().then(books => {
this.books = books;
});
},
});
<APP-SCI-FI-BOOKS-LIST> (update)
SOLUTION FOR SCI-FI-BOOKS
app.component(‘appSciFiBooksList’, {
template: ‘…’,
controller(booksService, $scope) {
getSciFiBooks();
$scope.$on(‘booksChanged’, getSciFiBooks);
function getSciFiBooks() {
booksService.getList().then(books => {
this.books = books.filter(isSciFi);
});
}
},
});
It smells to a service function…
Hierarchy
SOLUTION FOR SCI-FI-BOOKS
book
Service
sciFiBooks
Service
is listened
calls
Main Rule: no cycles of the arrow same color
Hierarchy
SOLUTION FOR SCI-FI-BOOKS
product
Service
Main Rule: no cycles of the arrow same color
showroom
Service
user
Service
cart
Service
shipping
Service
payment
method
Service
addresses
Service
MVS: MVC IN
ANGULAR
FRONT MVC
the same flow
MVS
SERVICES
MODELS VIEWS
calls
updates
are $watched
the same flow
MVS
SERVICES
MODELS
VIEWS
calls
updates
are $watched
Dumb
Views
Smart
Views
BROWSER
uses listens
uses listens
the same flow
MVS
SERVICES
MODELS
VIEWS
calls
updates
are $watched
Dumb
Views
Smart
Views
BROWSER
uses listens
uses listens
Services
Remotes Storages
callscalls
the same flow
MVS
SERVICES
MODELS VIEWS
calls
updates
are $watched
Dumb
Views
Smart
Views
BROWSER
uses listens
uses listens
Services
Remotes Storages
callscalls
State
Holders
State
Singletons
State
Dictionaries
CI
CI
CICICI
computed data flow
MVS
SERVICES
MODELS VIEWS
calls
updates
are $watched
Dumb
Views
Smart
Views
BROWSER
uses listens
uses listens
Services
Remotes Storages
callscalls
State
Holders
State
Singletons
State
Dictionaries
CI
CI
CICICI
computed data flow
MVS
SERVICES
MODELS VIEWS
calls
updates
are $watched
Dumb
Views
Smart
Views
BROWSER
uses listens
uses listens
Services
Remotes Storages
callscalls
State
Holders
State
Singletons
State
Dictionaries
CI
CI
CICICI
are listened
are listened
step by step
COMPUTED DATA FLOW
1. call
5. is fired
Books
Service
Books
Dictionary
Sci-Fi
Service
Sci-Fi
Dictionary
2. updates
3. fire $update
7. updates
8. fire $update
$UPDATE
EVENT MANAGER
4. fire $update
6. reads

More Related Content

What's hot

A single language for backend and frontend from AngularJS to cloud with Clau...
A single language for backend and frontend  from AngularJS to cloud with Clau...A single language for backend and frontend  from AngularJS to cloud with Clau...
A single language for backend and frontend from AngularJS to cloud with Clau...Walter Dal Mut
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesomeAndrew Hull
 
Barcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentationBarcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentationSociable
 
Getting Started with jQuery
Getting Started with jQueryGetting Started with jQuery
Getting Started with jQueryAkshay Mathur
 
Javascript Application Architecture with Backbone.JS
Javascript Application Architecture with Backbone.JSJavascript Application Architecture with Backbone.JS
Javascript Application Architecture with Backbone.JSMin Ming Lo
 
Developing iOS REST Applications
Developing iOS REST ApplicationsDeveloping iOS REST Applications
Developing iOS REST Applicationslmrei
 
Tools that get you laid
Tools that get you laidTools that get you laid
Tools that get you laidSwizec Teller
 
React && React Native workshop
React && React Native workshopReact && React Native workshop
React && React Native workshopStacy Goh
 
How AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsHow AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsRan Mizrahi
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery WidgetsGetting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgetsvelveeta_512
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Elena Kolevska
 
JavaScript Library Overview
JavaScript Library OverviewJavaScript Library Overview
JavaScript Library Overviewjeresig
 
Caldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW WorkshopCaldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW WorkshopCalderaLearn
 

What's hot (19)

Intro to ReactJS
Intro to ReactJSIntro to ReactJS
Intro to ReactJS
 
A single language for backend and frontend from AngularJS to cloud with Clau...
A single language for backend and frontend  from AngularJS to cloud with Clau...A single language for backend and frontend  from AngularJS to cloud with Clau...
A single language for backend and frontend from AngularJS to cloud with Clau...
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesome
 
Barcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentationBarcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentation
 
Getting Started with jQuery
Getting Started with jQueryGetting Started with jQuery
Getting Started with jQuery
 
Javascript Application Architecture with Backbone.JS
Javascript Application Architecture with Backbone.JSJavascript Application Architecture with Backbone.JS
Javascript Application Architecture with Backbone.JS
 
jQuery Introduction
jQuery IntroductionjQuery Introduction
jQuery Introduction
 
Developing iOS REST Applications
Developing iOS REST ApplicationsDeveloping iOS REST Applications
Developing iOS REST Applications
 
JQuery introduction
JQuery introductionJQuery introduction
JQuery introduction
 
Tools that get you laid
Tools that get you laidTools that get you laid
Tools that get you laid
 
React && React Native workshop
React && React Native workshopReact && React Native workshop
React && React Native workshop
 
How AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsHow AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design Patterns
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery WidgetsGetting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgets
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
JavaScript Library Overview
JavaScript Library OverviewJavaScript Library Overview
JavaScript Library Overview
 
Caldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW WorkshopCaldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW Workshop
 
jQuery
jQueryjQuery
jQuery
 
ReactJS for Beginners
ReactJS for BeginnersReactJS for Beginners
ReactJS for Beginners
 

Similar to MVS: An angular MVC

REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101Samantha Geitz
 
Single Page Applications on JavaScript and ASP.NET MVC4
Single Page Applications on JavaScript and ASP.NET MVC4Single Page Applications on JavaScript and ASP.NET MVC4
Single Page Applications on JavaScript and ASP.NET MVC4Yuriy Shapovalov
 
cake phptutorial
cake phptutorialcake phptutorial
cake phptutorialice27
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackNelson Glauber Leal
 
Prateek dayal backbonerails-110528024926-phpapp02
Prateek dayal backbonerails-110528024926-phpapp02Prateek dayal backbonerails-110528024926-phpapp02
Prateek dayal backbonerails-110528024926-phpapp02Revath S Kumar
 
Single Page Web Apps with Backbone.js and Rails
Single Page Web Apps with Backbone.js and RailsSingle Page Web Apps with Backbone.js and Rails
Single Page Web Apps with Backbone.js and RailsPrateek Dayal
 
Boosting Your Productivity, with Backbone & RactiveJS
Boosting Your Productivity, with Backbone & RactiveJS Boosting Your Productivity, with Backbone & RactiveJS
Boosting Your Productivity, with Backbone & RactiveJS Gabriel Gottgtroy Zigolis
 
The Django Book chapter 5 Models
The Django Book chapter 5 ModelsThe Django Book chapter 5 Models
The Django Book chapter 5 ModelsVincent Chien
 
MongoDB Days UK: Building Apps with the MEAN Stack
MongoDB Days UK: Building Apps with the MEAN StackMongoDB Days UK: Building Apps with the MEAN Stack
MongoDB Days UK: Building Apps with the MEAN StackMongoDB
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsMike Subelsky
 
RapidApp - YAPC::NA 2014
RapidApp - YAPC::NA 2014RapidApp - YAPC::NA 2014
RapidApp - YAPC::NA 2014Henry Van Styn
 
From Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) AgainFrom Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) Againjonknapp
 
Ruby on Rails - Introduction
Ruby on Rails - IntroductionRuby on Rails - Introduction
Ruby on Rails - IntroductionVagmi Mudumbai
 
Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Joe Keeley
 
Getting Started with Rails
Getting Started with RailsGetting Started with Rails
Getting Started with RailsBasayel Said
 
SPA using Rails & Backbone
SPA using Rails & BackboneSPA using Rails & Backbone
SPA using Rails & BackboneAshan Fernando
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackNelson Glauber Leal
 
SQL to NoSQL: Top 6 Questions
SQL to NoSQL: Top 6 QuestionsSQL to NoSQL: Top 6 Questions
SQL to NoSQL: Top 6 QuestionsMike Broberg
 

Similar to MVS: An angular MVC (20)

REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101
 
Single Page Applications on JavaScript and ASP.NET MVC4
Single Page Applications on JavaScript and ASP.NET MVC4Single Page Applications on JavaScript and ASP.NET MVC4
Single Page Applications on JavaScript and ASP.NET MVC4
 
cake phptutorial
cake phptutorialcake phptutorial
cake phptutorial
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
 
Prateek dayal backbonerails-110528024926-phpapp02
Prateek dayal backbonerails-110528024926-phpapp02Prateek dayal backbonerails-110528024926-phpapp02
Prateek dayal backbonerails-110528024926-phpapp02
 
Single Page Web Apps with Backbone.js and Rails
Single Page Web Apps with Backbone.js and RailsSingle Page Web Apps with Backbone.js and Rails
Single Page Web Apps with Backbone.js and Rails
 
Boosting Your Productivity, with Backbone & RactiveJS
Boosting Your Productivity, with Backbone & RactiveJS Boosting Your Productivity, with Backbone & RactiveJS
Boosting Your Productivity, with Backbone & RactiveJS
 
The Django Book chapter 5 Models
The Django Book chapter 5 ModelsThe Django Book chapter 5 Models
The Django Book chapter 5 Models
 
MongoDB Days UK: Building Apps with the MEAN Stack
MongoDB Days UK: Building Apps with the MEAN StackMongoDB Days UK: Building Apps with the MEAN Stack
MongoDB Days UK: Building Apps with the MEAN Stack
 
Introduction to AngularJS
Introduction to AngularJSIntroduction to AngularJS
Introduction to AngularJS
 
AngularJS - TechTalk 3/2/2014
AngularJS - TechTalk 3/2/2014AngularJS - TechTalk 3/2/2014
AngularJS - TechTalk 3/2/2014
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 
RapidApp - YAPC::NA 2014
RapidApp - YAPC::NA 2014RapidApp - YAPC::NA 2014
RapidApp - YAPC::NA 2014
 
From Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) AgainFrom Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) Again
 
Ruby on Rails - Introduction
Ruby on Rails - IntroductionRuby on Rails - Introduction
Ruby on Rails - Introduction
 
Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019
 
Getting Started with Rails
Getting Started with RailsGetting Started with Rails
Getting Started with Rails
 
SPA using Rails & Backbone
SPA using Rails & BackboneSPA using Rails & Backbone
SPA using Rails & Backbone
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
 
SQL to NoSQL: Top 6 Questions
SQL to NoSQL: Top 6 QuestionsSQL to NoSQL: Top 6 Questions
SQL to NoSQL: Top 6 Questions
 

More from David Rodenas

TDD CrashCourse Part2: TDD
TDD CrashCourse Part2: TDDTDD CrashCourse Part2: TDD
TDD CrashCourse Part2: TDDDavid Rodenas
 
TDD CrashCourse Part1: Testing
TDD CrashCourse Part1: TestingTDD CrashCourse Part1: Testing
TDD CrashCourse Part1: TestingDavid Rodenas
 
TDD CrashCourse Part3: TDD Techniques
TDD CrashCourse Part3: TDD TechniquesTDD CrashCourse Part3: TDD Techniques
TDD CrashCourse Part3: TDD TechniquesDavid Rodenas
 
TDD CrashCourse Part5: Testing Techniques
TDD CrashCourse Part5: Testing TechniquesTDD CrashCourse Part5: Testing Techniques
TDD CrashCourse Part5: Testing TechniquesDavid Rodenas
 
TDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingTDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingDavid Rodenas
 
Be professional: We Rule the World
Be professional: We Rule the WorldBe professional: We Rule the World
Be professional: We Rule the WorldDavid Rodenas
 
ES3-2020-P3 TDD Calculator
ES3-2020-P3 TDD CalculatorES3-2020-P3 TDD Calculator
ES3-2020-P3 TDD CalculatorDavid Rodenas
 
ES3-2020-P2 Bowling Game Kata
ES3-2020-P2 Bowling Game KataES3-2020-P2 Bowling Game Kata
ES3-2020-P2 Bowling Game KataDavid Rodenas
 
ES3-2020-07 Testing techniques
ES3-2020-07 Testing techniquesES3-2020-07 Testing techniques
ES3-2020-07 Testing techniquesDavid Rodenas
 
ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)David Rodenas
 
Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214David Rodenas
 
ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for ProgrammersDavid Rodenas
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS ProgrammersDavid Rodenas
 
Basic Tutorial of React for Programmers
Basic Tutorial of React for ProgrammersBasic Tutorial of React for Programmers
Basic Tutorial of React for ProgrammersDavid Rodenas
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxDavid Rodenas
 
From high school to university and work
From high school to university and workFrom high school to university and work
From high school to university and workDavid Rodenas
 
Freelance i Enginyeria
Freelance i EnginyeriaFreelance i Enginyeria
Freelance i EnginyeriaDavid Rodenas
 

More from David Rodenas (20)

TDD CrashCourse Part2: TDD
TDD CrashCourse Part2: TDDTDD CrashCourse Part2: TDD
TDD CrashCourse Part2: TDD
 
TDD CrashCourse Part1: Testing
TDD CrashCourse Part1: TestingTDD CrashCourse Part1: Testing
TDD CrashCourse Part1: Testing
 
TDD CrashCourse Part3: TDD Techniques
TDD CrashCourse Part3: TDD TechniquesTDD CrashCourse Part3: TDD Techniques
TDD CrashCourse Part3: TDD Techniques
 
TDD CrashCourse Part5: Testing Techniques
TDD CrashCourse Part5: Testing TechniquesTDD CrashCourse Part5: Testing Techniques
TDD CrashCourse Part5: Testing Techniques
 
TDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingTDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving Testing
 
Be professional: We Rule the World
Be professional: We Rule the WorldBe professional: We Rule the World
Be professional: We Rule the World
 
ES3-2020-P3 TDD Calculator
ES3-2020-P3 TDD CalculatorES3-2020-P3 TDD Calculator
ES3-2020-P3 TDD Calculator
 
ES3-2020-P2 Bowling Game Kata
ES3-2020-P2 Bowling Game KataES3-2020-P2 Bowling Game Kata
ES3-2020-P2 Bowling Game Kata
 
ES3-2020-07 Testing techniques
ES3-2020-07 Testing techniquesES3-2020-07 Testing techniques
ES3-2020-07 Testing techniques
 
ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)
 
ES3-2020-05 Testing
ES3-2020-05 TestingES3-2020-05 Testing
ES3-2020-05 Testing
 
Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214
 
ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for Programmers
 
Vespres
VespresVespres
Vespres
 
Faster web pages
Faster web pagesFaster web pages
Faster web pages
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS Programmers
 
Basic Tutorial of React for Programmers
Basic Tutorial of React for ProgrammersBasic Tutorial of React for Programmers
Basic Tutorial of React for Programmers
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicox
 
From high school to university and work
From high school to university and workFrom high school to university and work
From high school to university and work
 
Freelance i Enginyeria
Freelance i EnginyeriaFreelance i Enginyeria
Freelance i Enginyeria
 

Recently uploaded

Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Sonam Pathan
 
Elevate Your Business with Our IT Expertise in New Orleans
Elevate Your Business with Our IT Expertise in New OrleansElevate Your Business with Our IT Expertise in New Orleans
Elevate Your Business with Our IT Expertise in New Orleanscorenetworkseo
 
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书zdzoqco
 
Git and Github workshop GDSC MLRITM
Git and Github  workshop GDSC MLRITMGit and Github  workshop GDSC MLRITM
Git and Github workshop GDSC MLRITMgdsc13
 
Magic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMagic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMartaLoveguard
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一z xss
 
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)Christopher H Felton
 
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书rnrncn29
 
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一Fs
 
Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Paul Calvano
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Dana Luther
 
PHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationPHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationLinaWolf1
 
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一Fs
 
Contact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New DelhiContact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New Delhimiss dipika
 
Film cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasaFilm cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasa494f574xmv
 
Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Excelmac1
 
Top 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxTop 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxDyna Gilbert
 

Recently uploaded (20)

Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
 
Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170
 
Elevate Your Business with Our IT Expertise in New Orleans
Elevate Your Business with Our IT Expertise in New OrleansElevate Your Business with Our IT Expertise in New Orleans
Elevate Your Business with Our IT Expertise in New Orleans
 
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Serviceyoung call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
 
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
 
Git and Github workshop GDSC MLRITM
Git and Github  workshop GDSC MLRITMGit and Github  workshop GDSC MLRITM
Git and Github workshop GDSC MLRITM
 
Magic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMagic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptx
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
 
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
 
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
 
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
 
Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
 
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
 
PHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationPHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 Documentation
 
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
 
Contact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New DelhiContact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New Delhi
 
Film cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasaFilm cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasa
 
Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...Blepharitis inflammation of eyelid symptoms cause everything included along w...
Blepharitis inflammation of eyelid symptoms cause everything included along w...
 
Top 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxTop 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptx
 

MVS: An angular MVC

  • 2. THINGS WRONG THAT I DID TO FIT THINGS IN SLIDES DISCLAIMER • Directives should use controller and bindToController • Directives should never load resources, this should be done by routes or under demand • Use .factory to simplify and homogenize code
 (not .service neither .value) • In a previous talk I said that model was plain JS data, sorry 
 (plain data is the form, but does not defines a model) • Use better variable names
  • 3. MVC - MODEL THE GREAT FORGOTTEN FRONT MVC
  • 4. TYPICAL ANGULAR CODE AS SEEN ON SOME DOCS (AND FROM SOME BEGINNERS)
  • 5. TYPICAL ANGULAR CODE <APP-BOOKS-LIST> app.component(‘appBooksList’, { template: ‘…’, controller($http) { $http.get(‘/api/v1/books’).then(response => { this.books = response.data; }); }, });
  • 6. TYPICAL ANGULAR CODE <APP-SCI-FI-BOOKS-LIST> app.component(‘appSciFiBooksList’, { template: ‘…’, controller($http) { $http.get(‘/api/v1/books’).then(response => { this.books = response.data.filter(isSciFi); }); }, });
  • 7. REFACTORING - SERVICE THERE IS REPLICATED CODE ¡LET’S DO A SERVICE!
  • 8. REFACTORING - SERVICE booksService app.service(‘booksService’, ($http) => { this.getList = () => { return $http.get(‘/api/v1/books’).then(function(response) { return response.data; }); }; }); Acquires the responsibility for: • R1: Know the API context Url • R2: Create a remote connection • R3: Transform response into usable object
  • 9. REFACTORING - SERVICE <APP-BOOKS-LIST> & <APP-SCI-FI-BOOKS-LIST> app.component(‘appBooksList’, { template: ‘…’, controller(booksService) { booksService.getList().then(books => { this.books = books; }); }, }); app.component(‘appSciFiBooksList’, { template: ‘…’, controller(booksService) { booksService.getList().then(books => { this.books = books.filter(isSciFi); }); }, });
  • 10. PERFORMANCE - CACHING OPS! WE ARE LOADING DATA TWICE ¡LET’S DO A CACHE!
  • 11. PERFORMANCE - CACHING booksService Notice that: • Repairs all directives at once • Acquires one new responsibility (R4: manage cache) app.service(‘booksService’, ($http) => { this.getList = () => { return $http.get(‘/api/v1/books’, {cache:true}).then(response => { return response.data; }); }; });
  • 12. PERFORMANCE - CACHING booksService Notice that: • Repairs all directives at once • Acquires one new responsibility (R4: manage cache) app.service(‘booksService’, ($http) => { this.getList = () => { if (!this.list) { this.list = $http.get(‘/api/v1/books’).then(response => { return response.data; }); } return this.list; }; }); Alternate
  • 13. NEW FEATURE - ONE BOOK WE HAVE A VIEW THAT ONLY SHOWS ONE BOOK
  • 14. NEW FEATURE - ONE BOOK <APP-BOOK-VIEW BOOK-ID=“ID”> app.component(‘appBookView’, { template: ‘…’, bindings: { bookId: ‘<‘ }, controller: function(booksService) { booksService.get(this.bookId).then(book => { this.book = book; }); }, });
  • 15. NEW FEATURE - ONE BOOK booksService (step1) Notice that: • What about repeating loading of books (R4: manage cache) app.service(‘booksService’, ($http) => { this.loadAll = function() { return $http.get(‘/api/v1/books’, {cache:true}).then(response => { return response.data; }); }; this.load = (id) => { return $http.get(‘/api/v1/books/’+id).then(response => { return response.data; }); }; });
  • 16. NEW FEATURE - ONE BOOK booksService (step2) • Uhmmmm… about R4… managing caches app.service(‘booksService’, ($http) => { this.loadAll = function() { return $http.get(‘/api/v1/books’, {cache:true}).then(response => { return response.data; }); }; this.load = (id) => { return $http.get(‘/api/v1/books/’+id, {cache:true}).then(response => { return response.data; }); }; });
  • 17. NEW FEATURE - ONE BOOK WE ARE LOADING TWICE THE SAME BOOK! It happens when: • Loading one book • Loading all books
  • 18. NEW FEATURE - ONE BOOK OK… MAY BE IT’S OK LOAD TWICE BUT NOT MORE TIMES THE SAME BOOK “We keep it simple…”
  • 19. NEW FEATURE - UPDATE BOOK WE HAVE A VIEW THAT MAKES AN UPDATE OF A BOOK AND SHOWS THE CHANGES INTRODUCED BY API
  • 20. NEW FEATURE - UPDATE BOOK <APP-BOOK-UPDATE BOOK-ID=“ID”> app.component(‘appBookUpdate’, { template: ‘…’, bindings: { bookId: ‘<‘, } constructor(booksService) { booksService.load(this).then(book => { this.book = book; }); this.update = () => { booksService.update(this.book).then(updatedBook => { this.book = updatedBook; }); }; }; });
  • 21. NEW FEATURE - ONE BOOK booksService (step2) • Uhmmmm… about R4… managing caches app.service(‘booksService’, ($http) => { this.getList = () => { return $http.get(‘/api/v1/books’, {cache:true}).then(response => { return response.data; }); }; this.get = (id) => { return $http.get(‘/api/v1/books/’+id, {cache:true}) .then(response => { return response.data; }); }; this.update = (book) => { return $http.put(‘/api/v1/books/’+book.id) .then(function(response) { return response.data; }); }; });
  • 22. NEW FEATURE - UPDATE BOOK SHIT!
  • 23. NEW FEATURE - UPDATE BOOK SHIT! What about: • Cache? • What if we have a list side-by side, it is updated? • What if we have view and update side-by-side?
  • 24. NEW FEATURE - UPDATE BOOK SHIT! How to solve it? • New services? • Callbacks? • RxJS? • More caches? • Events?
  • 25. NEW FEATURE - UPDATE BOOK WHAT IS THE REAL PROBLEM?
  • 26. NEW FEATURE - UPDATE BOOK WHAT IS THE REAL PROBLEM? R4 (manage caches) is hidden another responsibility: • Single source of true We need a model!
  • 27. WHAT A MODEL IS NOT? • A model is not styles in the web • A model is not objects in the scope • A model is not objects stored in the browser (local,websql,…) • A model are not instances of any sort of data • A model is not plain data
  • 28. SINGLE SOURCE OF TRUE WHAT IS A MODEL? • You can find your model • There is only one instance for each “concept”
 (all books with the same id are the same object) • Models may be computed from other models • It does not matters how many views do you have, 
 all views use the same models
 (as do services also) That is something that ember programmers knows very well.
  • 29. REFACTOR - ADD MODEL Book app.value(‘Book’, function Book(id) { this.id = id; this.isSciFi = function() { return !!this.tags.sciFi; }; this.takeData = function(bookData) { angular.extend(this, bookData); }; }); We discover new responsibilities: • R5: update and extract information of a book
  • 30. REFACTOR - ADD MODEL booksDictionary app.value(‘booksDictionary’, (Book) => { this.list = []; this.map = {}; this.getOrCreate = (id) => { var book = this.map[id]; if (!book) { book = new Book(id); this.list.push(book); this.list.map[id] = book; }; return book; }; this.takeDatas = (bookDatas) => { bookInfos.forEach((bookData) => { this.getOrCreate(bookData.id).takeData(bookData); }); }; }); We discover new responsibilities: • R6: manage book instances to avoid replicates • R7: store books so anyone can access to them Note that list
 is also a model.
  • 31. booksService (loadAll) app.service(‘booksService’, (booksDictionary, $http) => { this.getList = () => { if (!this.list) { this.list = $http.get(‘/api/v1/books’).then(response => { booksDictionary.takeDatas(response.data); return booksDictionary.list; }); } return this.list; }); }; … }); REFACTOR - ADD MODEL getList returns always the same instance of list.
  • 32. booksService (load) app.service(‘booksService’, (booksDictionary, $http) => { … this.books = {}; this.load = (id) => { if (!this.books[id]) { this.books[id] = $http.get(‘/api/v1/books/’+id).then(response => { var book = booksDictionary.getOrCreate(id); book.takeData(reponse.data); return book; }); } return this.books[id]; }; … }); REFACTOR - ADD MODEL Load(id) returns always the same instance of book for the same id. And the instance will be contained by the list in getList.
  • 33. booksService (update) app.service(‘booksService’, (booksDictionary, $http) => { … this.update = (book) => { var id = book.id; this.books[id] = $http.put(‘/api/v1/books/’+id).then(response => { var book = booksDictionary.getOrCreate(id); book.takeData(response.data); return book; }); }; }); REFACTOR - ADD MODEL Update returns always the same instance than get and getList, regardless the input. And also updates the same instance.
  • 34. three layers REFACTOR - ADD MODEL SERVICES MODELS VIEWS calls updates are $watched
  • 35. NEW FEATURE - UPDATE BOOK DONE!
  • 36. NEW FEATURE - UPDATE BOOK DONE? What about Sci-Fi list? • Is computed:
 it has to be recomputed each time that a book o list changes
 • A filter is expensive • Watch a derive function is expensive • Watch all books (aka $watch(,,true)) is expensive
  • 37. NEW FEATURE - UPDATE BOOK SHIT! Solved in the next talk…
  • 39. three kinds of components ORIGINAL MVC CONTROLLERS MODELS VIEWS are listenedupdates are observed
  • 40. the truth ORIGINAL MVC MODELS VIEWS knows and queries are listenedupdates are observed knows and queries CONTROLLERS
  • 42. ORIGINAL MVC SHIT! It is not as beautiful and easy as it seems. May be it worked in ’78, with just few Kb… and low complexity, but now…
  • 43. FB comments about MVC ARCHITECTURES VARIATIONS https://youtu.be/nYkdrAPrdcw?t=10m20s
  • 44. FB comments about MVC ARCHITECTURES VARIATIONS “MVC works pretty well for small applications… but it doesn’t make room for new features.” “Flux is a single direction data flow, that avoids all the arrows going on all directions what makes really hard to understand the system.”
  • 45. FB comments about MVC ARCHITECTURES VARIATIONS “Let’s see a real good example: FB chat” “How we get to the point, so we were annoying our users so much the just they wanted us to fix chat?” “The problems here were: • The code has no structure • It was very imperative, that makes it fragile • It loose a lot of the original intend behind it, its hard to tell what it tries [to do] • Add more features only gets this code larger • We had our most annoying chat bug happen over and over • We were always fixing some pretty good edge case, the whole system was fragile • … • This code becomes more fragile with the time. • No member of the team wanted to touch it, they wanted to jump to any other bug.”
  • 47. AND COMMUNITY ALSO CONTRIBUTED… ARCHITECTURES VARIATIONS
  • 50. Key points are: • Single direction flow • Avoid imperative code • Decoupled state from views • Computed data consistency
 (example: cart.price = ∑item.price * item.quantity) ARCHITECTURES VARIATIONS
  • 51. mvc FROM MVC TO MVS MODELS VIEWS knows and queries are listenedupdates are observed knows and queries CONTROLLERS
  • 52. mvc-angular FROM MVC TO MVS MODELS VIEWS knows and queries are $watched CONTR OLLERS
  • 53. the same flow FROM MVC TO MVS SERVICES MODELS VIEWS calls updates are $watched
  • 54. MVS RULES (I) SERVICES MODELS VIEWS calls updates are $watched • Views can call to services • Services manages models • Models are watched by views through $watch • Views cannot modify models but temporary copies • Each services has its own models and do not modify other services models
  • 55. Key points are: • Single direction flow • Avoid imperative code • Decoupled state from views • Computed data consistency
 (example: sciFiBooks = books.filter(isSciFi)) ANGULAR MVS
  • 56. SOLUTION FOR SCI-FI-BOOKS • Create a new model for SciFiBooks • Add a method getSciFiBooks() to bookService • Recompute the list each time that an update() method is called
  • 58. BUT! It does not scale. ¿What happens with more kind of books? ¿What happens with more complex data? SOLUTION FOR SCI-FI-BOOKS
  • 59. SOLUTION FOR SCI-FI-BOOKS • We need a synchronization mechanism • ex: events or observables
  • 60. SOLUTION FOR COMPUTED VALUES MODELS • Models launch update: ex $broadcast(‘booksChanged’) for angular1 fire events
  • 61. SOLUTION FOR COMPUTED VALUES MODELS • Models launch update: ex $broadcast(‘booksChanged’)
 
 
 • Rules: • Each model has its own event (1 <-> 1) • We do not pass any information (ex: previous and new value) • Change event is fired by the Service that manages the model • Events can be debounced (multiple collapsed in one) rules fire events
  • 62. booksService (update) app.service(‘booksService’, (booksDictionary, $http, $broadcast) => { … this.update = (book) => { var id = book.id; this.books[id] = $http.put(‘/api/v1/books/’+id).then(response => { var book = booksDictionary.getOrCreate(id); book.takeData(response.data); $broadcast(‘booksChanged’); return book; }); }; }); SOLUTION FOR SCI-FI-BOOKS
  • 63. <APP-SCI-FI-BOOKS-LIST> (update) SOLUTION FOR SCI-FI-BOOKS app.component(‘appSciFiBooksList’, { template: ‘…’, controller(booksService, $scope) { getSciFiBooks(); $scope.$on(‘booksChanged’, getSciFiBooks); function getSciFiBooks() { booksService.getList().then(books => { this.books = books.filter(isSciFi); }); } }, });
  • 64. <APP-SCI-FI-BOOKS-LIST> (update) SOLUTION FOR SCI-FI-BOOKS app.component(‘appSciFiBooksList’, { template: ‘…’, controller(booksService, $scope) { getSciFiBooks(); $scope.$on(‘booksChanged’, getSciFiBooks); function getSciFiBooks() { booksService.getList().then(books => { this.books = books.filter(isSciFi); }); } }, }); It smells to a service function…
  • 65. sciFiBooksService (update) app.service(‘sciFiBooksService’, (booksService, $rootScope) => { this.list = []; this.getList = () => this.list; updateList(); $rootScope.$on(‘booksChanged’, updateList); function updateList() { booksService.getList().then(books => { angular.copy(books.filter(isSciFi), this.list); $broadcast(‘sciFiChanged’); }); } }); SOLUTION FOR SCI-FI-BOOKS
  • 66. <APP-SCI-FI-BOOKS-LIST> (update) SOLUTION FOR SCI-FI-BOOKS app.component(‘appSciFiBooksList’, { template: ‘…’, controller(sciFiBooksService, $scope) { sciFiBooksService.getList().then(books => { this.books = books; }); }, });
  • 67. <APP-SCI-FI-BOOKS-LIST> (update) SOLUTION FOR SCI-FI-BOOKS app.component(‘appSciFiBooksList’, { template: ‘…’, controller(booksService, $scope) { getSciFiBooks(); $scope.$on(‘booksChanged’, getSciFiBooks); function getSciFiBooks() { booksService.getList().then(books => { this.books = books.filter(isSciFi); }); } }, }); It smells to a service function…
  • 68. Hierarchy SOLUTION FOR SCI-FI-BOOKS book Service sciFiBooks Service is listened calls Main Rule: no cycles of the arrow same color
  • 69. Hierarchy SOLUTION FOR SCI-FI-BOOKS product Service Main Rule: no cycles of the arrow same color showroom Service user Service cart Service shipping Service payment method Service addresses Service
  • 71. the same flow MVS SERVICES MODELS VIEWS calls updates are $watched
  • 72. the same flow MVS SERVICES MODELS VIEWS calls updates are $watched Dumb Views Smart Views BROWSER uses listens uses listens
  • 73. the same flow MVS SERVICES MODELS VIEWS calls updates are $watched Dumb Views Smart Views BROWSER uses listens uses listens Services Remotes Storages callscalls
  • 74. the same flow MVS SERVICES MODELS VIEWS calls updates are $watched Dumb Views Smart Views BROWSER uses listens uses listens Services Remotes Storages callscalls State Holders State Singletons State Dictionaries CI CI CICICI
  • 75. computed data flow MVS SERVICES MODELS VIEWS calls updates are $watched Dumb Views Smart Views BROWSER uses listens uses listens Services Remotes Storages callscalls State Holders State Singletons State Dictionaries CI CI CICICI
  • 76. computed data flow MVS SERVICES MODELS VIEWS calls updates are $watched Dumb Views Smart Views BROWSER uses listens uses listens Services Remotes Storages callscalls State Holders State Singletons State Dictionaries CI CI CICICI are listened are listened
  • 77. step by step COMPUTED DATA FLOW 1. call 5. is fired Books Service Books Dictionary Sci-Fi Service Sci-Fi Dictionary 2. updates 3. fire $update 7. updates 8. fire $update $UPDATE EVENT MANAGER 4. fire $update 6. reads