SlideShare a Scribd company logo
1 of 22
Download to read offline
Custom 
Ember Data 
Adapters 
Oli Griffiths - @oligriffiths 
Self 
Defining 
Apps
Custom Ember Data 
Adapters 
Oli Griffiths - @oligriffiths
Custom Ember Data Adapters 
• Interface between Ember Data identity mapper 
store and some external data store 
• Provides methods to find, create, update and 
delete records in external data store 
• External data store can be anything you like, 
REST API, SOAP API, RSS Feed, LocalStorage… 
Oli Griffiths - @oligriffiths
Custom Ember Data Adapters 
//Set the adapter as the application adapter 
//Rest API adapter 
App.ApplicationAdapter = DS.RestAdapter.extend() 
//Fixture (in memory only) 
App.ApplicationAdapter = DS.FixtureAdapter.extend() 
//Rails active record adapter 
App.ApplicationAdapter = DS.ActiveModelAdapter.extend() 
//A custom adapter 
App.ApplicationAdapter = CustomAdapter.extend() 
Oli Griffiths - @oligriffiths
Custom Ember Data Adapters 
var CustomAdapter = DS.Adapter.extend({ 
/** 
@method find 
@param {DS.Store} store 
@param {subclass of DS.Model} type 
@param {String} id 
@return {Promise} promise 
*/ 
find: function(store, type, url) {}, 
/** 
@private 
@method findAll 
@param {DS.Store} store 
@param {subclass of DS.Model} type 
@param {String} sinceToken 
@return {Promise} promise 
*/ 
findAll: function(store, type) {}, 
Oli Griffiths - @oligriffiths
Custom Ember Data Adapters 
/** 
@private 
@method findQuery 
@param {DS.Store} store 
@param {subclass of DS.Model} type 
@param {Object} query 
@param {DS.AdapterPopulatedRecordArray} recordArray 
@return {Promise} promise 
*/ 
findQuery: function(store, type, query, array) {}, 
/** 
@method createRecord 
@param {DS.Store} store 
@param {subclass of DS.Model} type 
@param {DS.Model} record 
@return {Promise} promise 
*/ 
createRecord: function(store, type, record) {}, 
Oli Griffiths - @oligriffiths
Custom Ember Data Adapters 
/** 
@method updateRecord 
@param {DS.Store} store 
@param {subclass of DS.Model} type 
@param {DS.Model} record 
@return {Promise} promise 
*/ 
updateRecord: function(store, type, record) {}, 
/** 
@method deleteRecord 
@param {DS.Store} store 
@param {subclass of DS.Model} type 
@param {DS.Model} record 
@return {Promise} promise 
*/ 
deleteRecord: function(store, type, record) {} 
Oli Griffiths - @oligriffiths
REST Adapter Example 
find: function(store, type, id) { 
return this.ajax(this.buildURL(type.typeKey, id), 'GET'); 
}, 
findAll: function(store, type, sinceToken) { 
var query; 
if (sinceToken) { 
query = { since: sinceToken }; 
} 
return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query }); 
}, 
findQuery: function(store, type, query) { 
return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query }); 
}, 
Oli Griffiths - @oligriffiths
REST Adapter Example 
createRecord: function(store, type, record) { 
var data = {}; 
var serializer = store.serializerFor(type.typeKey); 
serializer.serializeIntoHash(data, type, record, { includeId: true }); 
return this.ajax(this.buildURL(type.typeKey), "POST", { data: data }); 
}, 
updateRecord: function(store, type, record) { 
var data = {}; 
var serializer = store.serializerFor(type.typeKey); 
serializer.serializeIntoHash(data, type, record); 
var id = get(record, 'id'); 
return this.ajax(this.buildURL(type.typeKey, id), "PUT", { data: data }); 
}, 
deleteRecord: function(store, type, record) { 
var id = get(record, 'id'); 
return this.ajax(this.buildURL(type.typeKey, id), "DELETE"); 
}, 
Oli Griffiths - @oligriffiths
Custom Ember Data Adapters 
• Do not store data within the adapter 
• Merely transport data from the local data store to 
some “external” data store 
• Serializers are used to convert the data format 
to/from the local object representation to/from 
the “external” data store format 
Oli Griffiths - @oligriffiths
Self Defining Apps 
Oli Griffiths - @oligriffiths
What is a Self Defining App? 
• When the full functionality of an app is unknown 
at “build time” (when the developer writes the application) 
• Additional app functionality is created at runtime 
based on external dependencies 
• Thus the app “builds” itself whilst running 
Oli Griffiths - @oligriffiths
Ember: route first mentality 
Oli Griffiths - @oligriffiths 
PizzaRoute 
PizzaController 
PizzaModel 
PizzaView
What if your routes are unknown 
at build time? 
Oli Griffiths - @oligriffiths 
?Route 
?Controller 
?Model 
?View
What if your routes are unknown 
at build time? 
• You have a problem, everything depends on 
routes 
• Without defined routes, transitioning to a view is 
impossible 
• Some websites do not have pattern-able routes, 
so how can you define routes at “build time” 
Oli Griffiths - @oligriffiths
So how can we handle this? 
• Wild card routes allow you to register a route in 
the eventuality that no corresponding route is 
found 
• Wild card routes are intended to catch when a 
user tries to transition to an undefined route and 
show an error page 
• We can use this functionality to our advantage to 
build new routes at runtime 
Oli Griffiths - @oligriffiths
So how can we handle this? 
Oli Griffiths - @oligriffiths 
• Here is the flow: 
1. In the model hook, create an ember valid route name 
based off the URL being transitioned to 
2. Make an ajax request to the URL you’re attempting to 
transition to (swap .html to .json, or however your API works) 
3. Extract an identifying property from the response, 
perhaps “type” or “model” 
4. Register the URL (path) against the created route name 
from (1)
So how we can handle this? 
5. Register a new route instance in the application 
container, manually setting the controller, view 
and template name 
6. Transition to the newly defined route 
Oli Griffiths - @oligriffiths
What’s this look like? 
App.CatchAllRoute = Ember.Route.extend({ 
model: function(params, transition) 
{ 
//Get the URL and convert to route name 
var url = transition.intent.url; 
var route_name = Ember.String.classify(url.replace(/[.|-|/]+/g,'_')); 
//Check if route already exists, if so, transition to it 
var route = route_name ? this.container.resolve('route:'+route_name) : null; 
if(route) return this.transitionTo(route_name); 
//Get the data loader and load the data for the destination url 
var resolver = this.container.lookup(‘resolver:entity'); 
//Make an ajax request to the endpoint to get the endpoint data 
return resolver.request(url).then(function(data){ 
//Get the type from the response model property 
var type = data.model; 
//If no route is set (index) then set the route name to the type 
if(!route_name) route_name = type; 
Oli Griffiths - @oligriffiths
What’s this look like? 
//Add a new route for the url in question 
App.Router.map(function(){ 
this.resource(route_name, {path: url}); 
}); 
//Register new route, manually setting the controller,template and view names 
this.container.register('route:'+route_name, Ember.Route.extend({ 
controllerName: type, 
viewName: type, 
templateName: type, 
Oli Griffiths - @oligriffiths 
! 
model: function(){ 
var plural = type.substr(-1) == 's'; 
var name = plural ? type.substr(0, type.length-1) : type; 
if(!plural) return this.store.find(name, url); 
return this.store.filter(name, {url: url}, function(entity){ 
//filter model data if applicable 
}.bind(this)); 
} 
}));
What’s this look like? 
! 
//Transition to new route 
return this.transitionTo(route_name); 
}.bind(this), function(data){ 
//Force a manual page change 
document.location.href = url; 
Oli Griffiths - @oligriffiths 
}); 
! } 
}) 
! 
App.ApplicationView = Ember.View.extend({ 
didInsertElement: function() 
{ 
//Setup click handler to trigger transition 
this.$().on('click', 'a', function(e){ 
var a = $(e.target).closest('a'); 
//Ensure only links on this domain are captured 
if(a.prop('origin') != document.location.origin) return; 
//Stop default browser handler 
e.preventDefault(); 
! 
//Now you can transition to any route within a view using a links url 
this.controller.transitionToRoute(a.prop(‘pathname’)); 
}) 
} 
})
Demo time 
Oli Griffiths - @oligriffiths

More Related Content

Similar to Ember.js Self Defining Apps

Build Location Based App on bada
Build Location Based App on badaBuild Location Based App on bada
Build Location Based App on badaCheng Luo
 
EmberJS BucharestJS
EmberJS BucharestJSEmberJS BucharestJS
EmberJS BucharestJSRemus Rusanu
 
Introducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverIntroducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverSpike Brehm
 
REST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in CodeigniterREST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in CodeigniterSachin G Kulkarni
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
Method based views in django applications
Method based views in django applicationsMethod based views in django applications
Method based views in django applicationsGary Reynolds
 
Sahana Eden : Introduction to the Code (SahanaCamp 1.2)
Sahana Eden : Introduction to the Code (SahanaCamp 1.2)Sahana Eden : Introduction to the Code (SahanaCamp 1.2)
Sahana Eden : Introduction to the Code (SahanaCamp 1.2)AidIQ
 
Services Drupalcamp Stockholm 2009
Services Drupalcamp Stockholm 2009Services Drupalcamp Stockholm 2009
Services Drupalcamp Stockholm 2009hugowetterberg
 
iOS Swift application architecture
iOS Swift application architectureiOS Swift application architecture
iOS Swift application architectureRomain Rochegude
 
Custom Forms and Configuration Forms in Drupal 8
Custom Forms and Configuration Forms in Drupal 8Custom Forms and Configuration Forms in Drupal 8
Custom Forms and Configuration Forms in Drupal 8Italo Mairo
 
Resource Routing in ExpressionEngine
Resource Routing in ExpressionEngineResource Routing in ExpressionEngine
Resource Routing in ExpressionEngineMichaelRog
 
Api development with rails
Api development with railsApi development with rails
Api development with railsEdwin Cruz
 
Mock Servers - Fake All the Things!
Mock Servers - Fake All the Things!Mock Servers - Fake All the Things!
Mock Servers - Fake All the Things!Atlassian
 
Great APIs - Future of Your Progress App
Great APIs - Future of Your Progress AppGreat APIs - Future of Your Progress App
Great APIs - Future of Your Progress AppGabriel Lucaciu
 
Spring MVC Annotations
Spring MVC AnnotationsSpring MVC Annotations
Spring MVC AnnotationsJordan Silva
 
ASP.NET Routing & MVC
ASP.NET Routing & MVCASP.NET Routing & MVC
ASP.NET Routing & MVCEmad Alashi
 

Similar to Ember.js Self Defining Apps (20)

Build Location Based App on bada
Build Location Based App on badaBuild Location Based App on bada
Build Location Based App on bada
 
EmberJS BucharestJS
EmberJS BucharestJSEmberJS BucharestJS
EmberJS BucharestJS
 
Introducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverIntroducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and server
 
REST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in CodeigniterREST API Best Practices & Implementing in Codeigniter
REST API Best Practices & Implementing in Codeigniter
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Method based views in django applications
Method based views in django applicationsMethod based views in django applications
Method based views in django applications
 
Refactoring
RefactoringRefactoring
Refactoring
 
Sahana Eden : Introduction to the Code (SahanaCamp 1.2)
Sahana Eden : Introduction to the Code (SahanaCamp 1.2)Sahana Eden : Introduction to the Code (SahanaCamp 1.2)
Sahana Eden : Introduction to the Code (SahanaCamp 1.2)
 
Services Drupalcamp Stockholm 2009
Services Drupalcamp Stockholm 2009Services Drupalcamp Stockholm 2009
Services Drupalcamp Stockholm 2009
 
iOS Swift application architecture
iOS Swift application architectureiOS Swift application architecture
iOS Swift application architecture
 
Workshop 17: EmberJS parte II
Workshop 17: EmberJS parte IIWorkshop 17: EmberJS parte II
Workshop 17: EmberJS parte II
 
Custom Forms and Configuration Forms in Drupal 8
Custom Forms and Configuration Forms in Drupal 8Custom Forms and Configuration Forms in Drupal 8
Custom Forms and Configuration Forms in Drupal 8
 
Resource Routing in ExpressionEngine
Resource Routing in ExpressionEngineResource Routing in ExpressionEngine
Resource Routing in ExpressionEngine
 
Api development with rails
Api development with railsApi development with rails
Api development with rails
 
Mock Servers - Fake All the Things!
Mock Servers - Fake All the Things!Mock Servers - Fake All the Things!
Mock Servers - Fake All the Things!
 
Great APIs - Future of Your Progress App
Great APIs - Future of Your Progress AppGreat APIs - Future of Your Progress App
Great APIs - Future of Your Progress App
 
Spring MVC Annotations
Spring MVC AnnotationsSpring MVC Annotations
Spring MVC Annotations
 
ASP.NET Routing & MVC
ASP.NET Routing & MVCASP.NET Routing & MVC
ASP.NET Routing & MVC
 
Workshop 16: EmberJS Parte I
Workshop 16: EmberJS Parte IWorkshop 16: EmberJS Parte I
Workshop 16: EmberJS Parte I
 
Complex Sites with Silex
Complex Sites with SilexComplex Sites with Silex
Complex Sites with Silex
 

Recently uploaded

#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 

Recently uploaded (20)

#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 

Ember.js Self Defining Apps

  • 1. Custom Ember Data Adapters Oli Griffiths - @oligriffiths Self Defining Apps
  • 2. Custom Ember Data Adapters Oli Griffiths - @oligriffiths
  • 3. Custom Ember Data Adapters • Interface between Ember Data identity mapper store and some external data store • Provides methods to find, create, update and delete records in external data store • External data store can be anything you like, REST API, SOAP API, RSS Feed, LocalStorage… Oli Griffiths - @oligriffiths
  • 4. Custom Ember Data Adapters //Set the adapter as the application adapter //Rest API adapter App.ApplicationAdapter = DS.RestAdapter.extend() //Fixture (in memory only) App.ApplicationAdapter = DS.FixtureAdapter.extend() //Rails active record adapter App.ApplicationAdapter = DS.ActiveModelAdapter.extend() //A custom adapter App.ApplicationAdapter = CustomAdapter.extend() Oli Griffiths - @oligriffiths
  • 5. Custom Ember Data Adapters var CustomAdapter = DS.Adapter.extend({ /** @method find @param {DS.Store} store @param {subclass of DS.Model} type @param {String} id @return {Promise} promise */ find: function(store, type, url) {}, /** @private @method findAll @param {DS.Store} store @param {subclass of DS.Model} type @param {String} sinceToken @return {Promise} promise */ findAll: function(store, type) {}, Oli Griffiths - @oligriffiths
  • 6. Custom Ember Data Adapters /** @private @method findQuery @param {DS.Store} store @param {subclass of DS.Model} type @param {Object} query @param {DS.AdapterPopulatedRecordArray} recordArray @return {Promise} promise */ findQuery: function(store, type, query, array) {}, /** @method createRecord @param {DS.Store} store @param {subclass of DS.Model} type @param {DS.Model} record @return {Promise} promise */ createRecord: function(store, type, record) {}, Oli Griffiths - @oligriffiths
  • 7. Custom Ember Data Adapters /** @method updateRecord @param {DS.Store} store @param {subclass of DS.Model} type @param {DS.Model} record @return {Promise} promise */ updateRecord: function(store, type, record) {}, /** @method deleteRecord @param {DS.Store} store @param {subclass of DS.Model} type @param {DS.Model} record @return {Promise} promise */ deleteRecord: function(store, type, record) {} Oli Griffiths - @oligriffiths
  • 8. REST Adapter Example find: function(store, type, id) { return this.ajax(this.buildURL(type.typeKey, id), 'GET'); }, findAll: function(store, type, sinceToken) { var query; if (sinceToken) { query = { since: sinceToken }; } return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query }); }, findQuery: function(store, type, query) { return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query }); }, Oli Griffiths - @oligriffiths
  • 9. REST Adapter Example createRecord: function(store, type, record) { var data = {}; var serializer = store.serializerFor(type.typeKey); serializer.serializeIntoHash(data, type, record, { includeId: true }); return this.ajax(this.buildURL(type.typeKey), "POST", { data: data }); }, updateRecord: function(store, type, record) { var data = {}; var serializer = store.serializerFor(type.typeKey); serializer.serializeIntoHash(data, type, record); var id = get(record, 'id'); return this.ajax(this.buildURL(type.typeKey, id), "PUT", { data: data }); }, deleteRecord: function(store, type, record) { var id = get(record, 'id'); return this.ajax(this.buildURL(type.typeKey, id), "DELETE"); }, Oli Griffiths - @oligriffiths
  • 10. Custom Ember Data Adapters • Do not store data within the adapter • Merely transport data from the local data store to some “external” data store • Serializers are used to convert the data format to/from the local object representation to/from the “external” data store format Oli Griffiths - @oligriffiths
  • 11. Self Defining Apps Oli Griffiths - @oligriffiths
  • 12. What is a Self Defining App? • When the full functionality of an app is unknown at “build time” (when the developer writes the application) • Additional app functionality is created at runtime based on external dependencies • Thus the app “builds” itself whilst running Oli Griffiths - @oligriffiths
  • 13. Ember: route first mentality Oli Griffiths - @oligriffiths PizzaRoute PizzaController PizzaModel PizzaView
  • 14. What if your routes are unknown at build time? Oli Griffiths - @oligriffiths ?Route ?Controller ?Model ?View
  • 15. What if your routes are unknown at build time? • You have a problem, everything depends on routes • Without defined routes, transitioning to a view is impossible • Some websites do not have pattern-able routes, so how can you define routes at “build time” Oli Griffiths - @oligriffiths
  • 16. So how can we handle this? • Wild card routes allow you to register a route in the eventuality that no corresponding route is found • Wild card routes are intended to catch when a user tries to transition to an undefined route and show an error page • We can use this functionality to our advantage to build new routes at runtime Oli Griffiths - @oligriffiths
  • 17. So how can we handle this? Oli Griffiths - @oligriffiths • Here is the flow: 1. In the model hook, create an ember valid route name based off the URL being transitioned to 2. Make an ajax request to the URL you’re attempting to transition to (swap .html to .json, or however your API works) 3. Extract an identifying property from the response, perhaps “type” or “model” 4. Register the URL (path) against the created route name from (1)
  • 18. So how we can handle this? 5. Register a new route instance in the application container, manually setting the controller, view and template name 6. Transition to the newly defined route Oli Griffiths - @oligriffiths
  • 19. What’s this look like? App.CatchAllRoute = Ember.Route.extend({ model: function(params, transition) { //Get the URL and convert to route name var url = transition.intent.url; var route_name = Ember.String.classify(url.replace(/[.|-|/]+/g,'_')); //Check if route already exists, if so, transition to it var route = route_name ? this.container.resolve('route:'+route_name) : null; if(route) return this.transitionTo(route_name); //Get the data loader and load the data for the destination url var resolver = this.container.lookup(‘resolver:entity'); //Make an ajax request to the endpoint to get the endpoint data return resolver.request(url).then(function(data){ //Get the type from the response model property var type = data.model; //If no route is set (index) then set the route name to the type if(!route_name) route_name = type; Oli Griffiths - @oligriffiths
  • 20. What’s this look like? //Add a new route for the url in question App.Router.map(function(){ this.resource(route_name, {path: url}); }); //Register new route, manually setting the controller,template and view names this.container.register('route:'+route_name, Ember.Route.extend({ controllerName: type, viewName: type, templateName: type, Oli Griffiths - @oligriffiths ! model: function(){ var plural = type.substr(-1) == 's'; var name = plural ? type.substr(0, type.length-1) : type; if(!plural) return this.store.find(name, url); return this.store.filter(name, {url: url}, function(entity){ //filter model data if applicable }.bind(this)); } }));
  • 21. What’s this look like? ! //Transition to new route return this.transitionTo(route_name); }.bind(this), function(data){ //Force a manual page change document.location.href = url; Oli Griffiths - @oligriffiths }); ! } }) ! App.ApplicationView = Ember.View.extend({ didInsertElement: function() { //Setup click handler to trigger transition this.$().on('click', 'a', function(e){ var a = $(e.target).closest('a'); //Ensure only links on this domain are captured if(a.prop('origin') != document.location.origin) return; //Stop default browser handler e.preventDefault(); ! //Now you can transition to any route within a view using a links url this.controller.transitionToRoute(a.prop(‘pathname’)); }) } })
  • 22. Demo time Oli Griffiths - @oligriffiths