SlideShare a Scribd company logo
Front End Workshops
EmberJS - In Depth
Marc Torrent & Mario García
mgarcia@visual-engin.com
mtorrent@visual-engin.com
In previous workshops of
EmberJS...
Remember the
BIG PICTURE
ember-cli Router
Routes
application.js
Models
Templates
Components
Ember-Data
Controllers
S
E
R
V
I
C
E
S
Ember Data - Adapters &
Serializers
Ember Data
Application
Route/Controller/Component
Can be thought as a read-through cache
Single store - Central repository of models in your application
Beware of cache-backend desynchronization!
Ember Data
Communication with backend
How we access data
DS.Adapter
DS.Serializer
As of Ember Data 2.0, the default Adapter and Serializer follow JSON API format.
REST API
Ember
Ember Data
Format of the data
JSON API Specification
Content-Type: application/vnd.api+json
Top level attribute “data”
Attribute names are dasherized
Attribute “type” should be pluralized
It’s about the data...
JSON API Specification
..but also about the end points!
Action HTTP Verb URL Response status*
Find GET /articles/123
200 - Successful
404 - Not found
Find All GET /articles
200 - Successful
404 - Not found
Update PATCH /articles/123
200 - Successful
204 - No Content
Create POST /articles
201 - Created
204 - No Content
Delete DELETE /articles/123
200 - Successful
204 - No Content
*More response statuses are possible. See the complete specification at http://jsonapi.org/format/
Adapters
Extend/build your own adapters to fit your needs!
Priority rules apply between adapters!
DS.Adapter
DS.JSONAPIAdapter
DS.RESTAdapter
How to communicate with backend
Customize your adapter (1 of 3)
// app/adapters/application.js
export default DS.JSONAPIAdapter.extend({
host: 'https://api.example.com',
namespace: 'api/v1'
});
store.findRecord('post', 1) GET request to http://api.example.com/api/v1/posts/1
Host customization - Endpoint path customization
store.findAll('person') GET request to http://api.example.com/api/v1/people
store.findAll('user-profile') GET request to http://api.example.com/api/v1/user-profiles
Customize your adapter (2 of 3)
Type path customization
// app/adapters/application.js
export default DS.JSONAPIAdapter.extend({
pathForType(type) {
return Ember.String.underscore(type);
}
});
store.findRecord('post', 1) GET request to /post/1
store.findAll('person') GET request to /person
store.findAll('user-profile') GET request to /user_profile
Headers customization
// app/adapters/application.js
export default DS.JSONAPIAdapter.extend({
headers: {
'API_KEY': 'secret key',
'ANOTHER_HEADER': 'Some header value'
}
});
Customize your adapter (3 of 3)
Pluralization customization
Ember Inflector at your rescue!
Allows definition of irregular and uncountable pluralizations
Houston...
Our API REST serves at the following endpoints:
➔ /formulae (instead of the regular form /formulas)
➔ /advice (instead of the pluralized form /advices)
...do we have a PROBLEM?
Serializers
DS.Serializer
DS.JSONAPISerializer
DS.JSONSerializer
DS.RESTSerializer
Extend/build your own serializers to fit your needs!
Priority rules apply between serializers!
Define the format of the data
Serializing data sent to backend
Customize your serializer (1 of 4)
// JSON generated by Ember Data
{
"data": {
"attributes": {
"name": "Product",
"amount": 100,
"currency": "SEK"
},
"type": "product"
}
}
// But server expects...
{
"data": {
"attributes": {
"name": "Product",
"cost": {
"amount": 100,
"currency": "SEK"
}
},
"type": "product"
}
}
Change the format of the data sent to backend with the serialize() hook.
Normalizing data received from backend
Customize your serializer (2 of 4)
// Server response
{
"id": "1",
"body": "A comment!",
"date": {
"offset": "GMT+0200 (CEST)",
"value": "Tue Apr 05 2016"
}
}
// But Ember Data expects...
{
"id": "1",
"body": "A comment!",
"offset": "GMT+0200 (CEST)",
"value": "Tue Apr 05 2016"
}
Change the format of the data received from backend with the
normalizeResponse() hook.
Identifier
Customize your serializer (3 of 4)
Specify your resource identifier key
through primaryKey property
export default DS.JSONSerializer.extend({
primaryKey: '_id'
});
Attribute names
If the JSON payload does not match your Ember model attribute names...
// app/models/person.js
export default DS.Model.extend({
lastName: DS.attr('string')
});
// app/serializers/person.js
export default DS.JSONAPISerializer.extend({
attrs: {
lastName: 'lastNameOfPerson'
}
});
Custom transforms
Customize your serializer (4 of 4)
Use custom transforms if the server sends data that does not fit any Ember Data
built-in attributes (string, number, boolean and date)
A custom transform should implement the serialize() and deserialize()
Once implemented, it can be used as a regular type of attribute
Routing and Navigation
Routing - Implicit routes
ember g route users
ember g route users/edit
application
application-loading
application-error
index
index-loading
index-error
users users-error
users/index
users-loading
users/edit
*All routes have its .hbs associated templates
loading
error
users/edit-error
users/edit-loading
users/index-loading
users/index-error
users/loading
users/error
Routing - Serve more than one model
Promises, promises, promises!
Ember.RSVP.hash resolves when all its promises parameters resolve
Be extra careful when using hash in the model() hook in cases where the hook
is not executed*
*See http://stackoverflow.com/questions/20521967/emberjs-how-to-load-multiple-models-on-the-same-route
Alternatively, you can use route nesting to load multiple models
More info in http://emberigniter.com/load-multiple-models-single-route/
Routing - Rendering a specific template
// app/routes/posts/new.js
export default Ember.Route.extend({
renderTemplate() {
this.render('posts/form');
}
});
It is possible to render a specific template through the renderTemplate()
hook.
DRY*!!!!!
*Don’t Repeat Yourself
// app/routes/posts/edit.js
export default Ember.Route.extend({
renderTemplate() {
this.render('posts/form');
}
});
Routing - Preventing and retrying transitions
Invoke transition.abort() to immediately abort the current transition
Store the transition object and re-attempt invoking transition.retry()
Every transition attempt fires the willTransition action on the current active
routes, starting with the leaf-most route
Ember Router passes a transition object to various hooks on the involved routes
export default Ember.Route.extend({
beforeModel(transition) {},
model(params, transition) {},
afterModel(model, transition) {}
});
Routing - Loading routes
When navigating to /users route, Ember will try to find loading templates*:
users-loading
loading or application-loading
The router pauses transitions until the promises returned from beforeModel,
model and afterModel hooks fulfill
An intermediate transition into a loading substate happens immediately
The URL won’t be updated on the loading transition
*See https://github.com/emberjs/ember.js/issues/12367
A loading event will be fired on that route
Routing - Error routes
When an error occurs navigating to /users, Ember will try to find templates*:
users-error
error or application-error
Analogous approach to loading substates in the case of errors
An intermediate transition into an error substate happens in case of thrown
error or rejected promise
The URL won’t be updated on the error transition
*See https://github.com/emberjs/ember.js/issues/12367
An error event will be fired on that route
Routing - Query params
{{#link-to "episodes" (query-params filter="simp")}}Episodes{{/link-to}}
transitionTo('episodes', { queryParams: { filter: 'simp' }});
Query params are declared on route-driven controllers
Use controller’s queryParams property to bind query params and URL
Query params to backend
Query params in frontend
transitionTo
link-to helper
store.query('episodes', { filter: 'simp' });
Templates
➢ Data Binding in template attributes
➢ Links
➢ Actions
➢ Input Helpers
➢ Write your own helpers
Data Binding in Templates
Controller’s Properties
<div class=”_tomster”>
<img src={{tomster.img}}
width=100>
</div>
DOM Attributes
<div class=”_tomster”>
<input type=”checkbox”
disabled={{tomster.disabled}}>
<img src={{tomster.img}}
width=100>
</div>
Collections
{{#each cartoons as |cartoon|}}
<div class=”_cartoon”>
<input type=”checkbox”
disabled={{cartoon.disabled}}>
<img src={{cartoon.img}}
width=100>
</div>
{{/each}}
Links: {{#link-to }}
A helper for links in our application without the need of using anchors and
href.
Router.map( function() {
this.route(‘about’);
this.route(‘cartoons’, function() {
this.route(‘cartoon’, {path: ‘/:cartoon_id’});
});
});
<ul>
{{#each model as |cartoon|}}
<li>{{#link-to "cartoons.cartoon"
cartoon}}{{cartoon.name}}{{/link-to}}
</li>
{{/each}}
</ul>
<ul>
<li><a href="/cartoon/1">Columbus Tomster</a></li>
<li><a href="/cartoon/2">LTS Tomster</a></li>
</ul>
Links: {{#link-to }} - Multiple Segments
We pass the model to the most inner nested route. The model() hook won’t be
called on routes where we specify the model through the link-to.
Router.map( function() {
this.route(‘cartoons’, function() {
this.route(cartoon, {path: ‘/:cartoon_id’},
function() {
this.route(‘specs’);
this.route(‘spec’, {path: ‘/specs/:
spec_id’});
});
});
});
<ul>
{{#each cartoons as |cartoon|}}
{{#each cartoon.specs as |spec|}}
<li>{{#link-to "cartoons.cartoon.
spec" spec}}{{spec.name}}{{/link-to}}
</li>
{{/each}}
{{/each}}
</ul>
Links: The Route that went away… (I)
Be careful with the structure of the templates and routes and beware of
models that you pass into the routes
Links: The Route that went away… (II)
Be careful with the structure of the templates and routes and beware of
models that you pass into the routes
Keep an eye on how you distribute your outlets and the relation between
index.hbs and the current template in our nested route.
Let’s see it in action!
Now you tell me what should I
place in the router - routes -
templates and link-to
Actions
1. Template helper for binding a DOM Event with a
Controller/Route/Component.
2. It can accept parameters such as Ember.Objects, Models or basic data
structures.
3. You can also specify the type of event by using the “on” option
4. By default, actions prevent the default browser action on a DOM Element.
To turn down this behavior, pass the option preventDefault=false
Input Helpers {{input}} {{textarea}}
1. Template helper for <input> and <textarea> DOM Elements.
2. Forget about actions with inputs and use the the input helpers as EmberJS
provides out of the box 2-way data-binding
3. Pass HTML and HTML5 attributes
4. Use it also with radio and checkboxes
Write Your Own Helpers
Custom template helpers for your own needs. Keep an eye on addons to see if
someone else has already written the helper you need.
ember generate helper
i18n
That file should export a function
wrapped with Ember.Helper.
helper()
The function receives a bundle
destination as string as the first
parameter (params[0]) and the key
to look for as the second parameter
(params[1])
To pass multiple arguments to a
helper, add them as a space-
separated list after the helper name
Use named Parameters to make
behavior of helpers configurable
export function i18n([bundle, key], {lang,
toUpperCase}) {
let resource = dictionary[bundle][key],
translation = lang? resource[lang] :
resource[DEFAULT_LANG];
return toUpperCase? translation.
toUpperCase() : translation;
}
export default Ember.Helper.helper(i18n);
<p>{{i18n "catalog" "category"
lang="es"}}</p>
<p>{{i18n "catalog" "category"}}</p>
<p>{{i18n "catalog" "category"}}</p>
<p>{{i18n "catalog" "product"
toUpperCase="true"}}</p>
Services
Routes
Controllers
Components
Helpers
...
Service
Persistent Object that can be
accessed for all the application
modules though:
Ember.inject.service()
Services - For What?
Services are useful for features that require shared state or persistent connections.
User/session authentication
Geolocation
Web Sockets
Server-sent events or notifications
Server-backed API calls that may
not fit Ember Data
Third-party APIs
Logging
Internationalization
Services - and How can I use it?
Create the Service:
ember generate service i18n
Services must extend the
Ember.Service base class:
Ember.Service.extend({});
Basic Service Advanced Service
Use the service in an Ember Object or
inherited:
i18n: Ember.inject.service()
The Service will be injected by the same
name we are assigning to a variable (i18n)
USE YOUR IMAGINATION, EVERYTHING
IS POSSIBLE!
Components
LA JOYA DE LA CORONA
AND ROUTABLE COMPONENTS ARE COMING!!
Components: Definition
➢ A reusable partial view (template with Handlebars) with controller that
can be combined with other components and contain other components.
❖ Components are used in route templates.
❖ They have a specific life cycle and can handle actions of their template and
also pass actions to their containing components, routes and controllers.
❖ At this moment components are not routable but soon they will become
routable and then, controllers will disappear.
❖ At this moment, EmberJS 2.4.0, All components need to be included inside
a template route that, by definition, has a Shim Controller.
❖ You can think of Components as widgets that are reusable through all our
application and that expose a template helper per usage.
ember generate component my-component
→ components/my-component.js
→ templates/my-component.hbs
<ul>
<li>{{my-component}}</li>
</ul>
Components: Passing Properties
➢ Pass Properties TOP - DOWN to components. Always from route
templates or other components to the destination component.
export default Ember.Route.extend({
model() {
return this.store.findAll('actor');
}
});
<ul>
{{#each model as |actor|}}
<li>{{actor-component actor=actor}}</li>
{{/each}}
</ul>
<div>{{actor.name}}<span {{action "toggleSection"}} style="margin-left: 5px;">{{more}}
</span></div>
{{#if showImage}}
<div><img src="{{actor.img}}" width="200px"></div>
{{/if}}
Components: Wrapping Content
➢ Let the developer use your component by passing custom content into it.
○ The template using your component will pass an html block inside the
component
○ The component MUST define the {{yield}} expression in its template
○ The component MUST be used in block form: {{#my-component}}...
{{/my-component}}
<div>{{yield}}<span {{action
"toggleSection"}}>{{more}}</span>
</div>
{{#if showImage}}
<div>
<img src="{{actor.img}}" width="200px">
</div>
{{/if}}
<ul>
{{#each model as |actor|}}
<li>{{#actor-component actor=actor}}
<p>{{actor.name}}</p>
{{/actor-component}}
</li>
{{/each}}
</ul>
Components: LifeCycle
➢ Access to hooks when the component is going to be rendered or
destroyed.
➢ It enables you to:
○ Direct DOM manipulation
○ Listening and responding to browser events
○ Using 3rd party JavaScript libraries in your Ember app
Initial Rendering:
1 init
2 didReceiveAttrs
3 willRender
4 didInsertElement
5 didRender
Re-Rendering:
1 didUpdateAttrs
2 didReceiveAttrs
3 willUpdate
4 willRender
5 didUpdate
Component Destroy:
1 willDestroyElement
2 willClearRender
3 didDestroyElement
6 didRender
Components: Data Down - Actions Up
➢ Keep the idea that state (properties) always travels in one direction:
TOP - DOWN.
➢ Instead, event handling (actions) always travel in the opposite direction:
BOTTOM-UP.
➢ Components and Controllers can handle actions from their contained
Components. See it as a data synchronization hub.
export default Ember.Component.extend({
actions: {
toggleSection() {
this.toggleProperty('showImage');
this.get('onSelected')(this);
}
}
export default Ember.Controller.extend({
actions: {
sectionShown(selectedActor) {
this.set('selectedActor', selectedActor);
}
}
});
{{actor-component actor=actor onSelected=(action "sectionShown")}}
Components: Transversal Communication
➢ In some situations components can not be on the same parent.
➢ We need a data-layer and a BUS using Pub-Sub
➢ For this purpose, use a Service extending Ember.Evented
export default Ember.Component.extend({
Appointment: Ember.inject.service(),
actions: {
complete() {
this.get(‘appointment’).trigger(‘complete’);
}
}
});
export default Ember.Component.extend({
appointment: Ember.inject.service(),
willRender() {
this.get(‘appoinment’).on(‘complete’,
this, ‘onComplete’);
},
onComplete() {
// Do Something
}
});
Integration with 3rd party
libraries
Integrate into the Ember using the asset manifest file ember-cli-build.js
Integration with 3rd party libraries
If an Ember addon exists... Install via Ember CLI and you are ready to go!
Front-end dependencies can be installed through Bower Package Manager
Other assets can (and should) just be placed in the vendor folder of the project
app.import({
development: 'bower_components/moment.js',
production: 'bower_components/moment.min.js'
});
app.import('vendor/amd.js', {
exports: {
'amd': ['raw', 'request']
}
});
Globals AMD Modules
Remember the
BIG PICTURE
ember-cli Router
Routes Models
Templates
Components
Ember-Data
Controllers
S
E
R
V
I
C
E
S
Thanks for your time!
Do you have any questions?
Workshop 17: EmberJS parte II

More Related Content

What's hot

Workshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & ReduxWorkshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & Redux
Visual Engineering
 
Workshop 22: React-Redux Middleware
Workshop 22: React-Redux MiddlewareWorkshop 22: React-Redux Middleware
Workshop 22: React-Redux Middleware
Visual Engineering
 
Workshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSWorkshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJS
Visual Engineering
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and Performance
Parashuram N
 
Using React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIsUsing React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIs
Mihail Gaberov
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
Natasha Murashev
 
Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)
Natasha Murashev
 
«От экспериментов с инфраструктурой до внедрения в продакшен»​
«От экспериментов с инфраструктурой до внедрения в продакшен»​«От экспериментов с инфраструктурой до внедрения в продакшен»​
«От экспериментов с инфраструктурой до внедрения в продакшен»​
FDConf
 
Asyc flow control with javascript generators - redux-saga
Asyc flow control with javascript generators - redux-sagaAsyc flow control with javascript generators - redux-saga
Asyc flow control with javascript generators - redux-saga
Pedro Solá
 
Practical Protocols with Associated Types
Practical Protocols with Associated TypesPractical Protocols with Associated Types
Practical Protocols with Associated Types
Natasha Murashev
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
TrevorBurnham
 
Academy PRO: React native - navigation
Academy PRO: React native - navigationAcademy PRO: React native - navigation
Academy PRO: React native - navigation
Binary Studio
 
Protocol-Oriented MVVM
Protocol-Oriented MVVMProtocol-Oriented MVVM
Protocol-Oriented MVVM
Natasha Murashev
 
Async JavaScript Unit Testing
Async JavaScript Unit TestingAsync JavaScript Unit Testing
Async JavaScript Unit Testing
Mihail Gaberov
 
How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescript
Katy Slemon
 
Protocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupProtocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS Meetup
Natasha Murashev
 
AngularJS.part1
AngularJS.part1AngularJS.part1
AngularJS.part1
Andrey Kolodnitsky
 
React.js or why DOM finally makes sense
React.js or why DOM finally makes senseReact.js or why DOM finally makes sense
React.js or why DOM finally makes sense
Eldar Djafarov
 
Intro to React
Intro to ReactIntro to React
Intro to React
Troy Miles
 
Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016
Nir Kaufman
 

What's hot (20)

Workshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & ReduxWorkshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & Redux
 
Workshop 22: React-Redux Middleware
Workshop 22: React-Redux MiddlewareWorkshop 22: React-Redux Middleware
Workshop 22: React-Redux Middleware
 
Workshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSWorkshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJS
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and Performance
 
Using React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIsUsing React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIs
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
 
Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)
 
«От экспериментов с инфраструктурой до внедрения в продакшен»​
«От экспериментов с инфраструктурой до внедрения в продакшен»​«От экспериментов с инфраструктурой до внедрения в продакшен»​
«От экспериментов с инфраструктурой до внедрения в продакшен»​
 
Asyc flow control with javascript generators - redux-saga
Asyc flow control with javascript generators - redux-sagaAsyc flow control with javascript generators - redux-saga
Asyc flow control with javascript generators - redux-saga
 
Practical Protocols with Associated Types
Practical Protocols with Associated TypesPractical Protocols with Associated Types
Practical Protocols with Associated Types
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
 
Academy PRO: React native - navigation
Academy PRO: React native - navigationAcademy PRO: React native - navigation
Academy PRO: React native - navigation
 
Protocol-Oriented MVVM
Protocol-Oriented MVVMProtocol-Oriented MVVM
Protocol-Oriented MVVM
 
Async JavaScript Unit Testing
Async JavaScript Unit TestingAsync JavaScript Unit Testing
Async JavaScript Unit Testing
 
How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescript
 
Protocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupProtocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS Meetup
 
AngularJS.part1
AngularJS.part1AngularJS.part1
AngularJS.part1
 
React.js or why DOM finally makes sense
React.js or why DOM finally makes senseReact.js or why DOM finally makes sense
React.js or why DOM finally makes sense
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016
 

Similar to Workshop 17: EmberJS parte II

Workshop 16: EmberJS Parte I
Workshop 16: EmberJS Parte IWorkshop 16: EmberJS Parte I
Workshop 16: EmberJS Parte I
Visual Engineering
 
Getting into ember.js
Getting into ember.jsGetting into ember.js
Getting into ember.js
reybango
 
RoR 101: Session 2
RoR 101: Session 2RoR 101: Session 2
RoR 101: Session 2
Rory Gianni
 
Using Amazon Simple Db With Rails
Using Amazon Simple Db With RailsUsing Amazon Simple Db With Rails
Using Amazon Simple Db With RailsAkhil Bansal
 
Ruby on Rails: Coding Guideline
Ruby on Rails: Coding GuidelineRuby on Rails: Coding Guideline
Ruby on Rails: Coding Guideline
Nascenia IT
 
Ams adapters
Ams adaptersAms adapters
Ams adapters
Bruno Alló Bacarini
 
Phoenix for Rails Devs
Phoenix for Rails DevsPhoenix for Rails Devs
Phoenix for Rails Devs
Diacode
 
Construction Techniques For Domain Specific Languages
Construction Techniques For Domain Specific LanguagesConstruction Techniques For Domain Specific Languages
Construction Techniques For Domain Specific LanguagesThoughtWorks
 
JS-05-Handlebars.ppt
JS-05-Handlebars.pptJS-05-Handlebars.ppt
JS-05-Handlebars.ppt
fakeaccount225095
 
Writing RESTful web services using Node.js
Writing RESTful web services using Node.jsWriting RESTful web services using Node.js
Writing RESTful web services using Node.js
FDConf
 
Rails Engine | Modular application
Rails Engine | Modular applicationRails Engine | Modular application
Rails Engine | Modular application
mirrec
 
IOC + Javascript
IOC + JavascriptIOC + Javascript
IOC + Javascript
Brian Cavalier
 
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
SPTechCon
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overviewYehuda Katz
 
Schema webinar
Schema webinarSchema webinar
Schema webinar
Gary Sherman
 
AEM Sightly Deep Dive
AEM Sightly Deep DiveAEM Sightly Deep Dive
AEM Sightly Deep Dive
Gabriel Walt
 
RequireJS
RequireJSRequireJS
RequireJS
Tim Doherty
 

Similar to Workshop 17: EmberJS parte II (20)

Workshop 16: EmberJS Parte I
Workshop 16: EmberJS Parte IWorkshop 16: EmberJS Parte I
Workshop 16: EmberJS Parte I
 
Getting into ember.js
Getting into ember.jsGetting into ember.js
Getting into ember.js
 
RoR 101: Session 2
RoR 101: Session 2RoR 101: Session 2
RoR 101: Session 2
 
Using Amazon Simple Db With Rails
Using Amazon Simple Db With RailsUsing Amazon Simple Db With Rails
Using Amazon Simple Db With Rails
 
Ruby on Rails: Coding Guideline
Ruby on Rails: Coding GuidelineRuby on Rails: Coding Guideline
Ruby on Rails: Coding Guideline
 
Ams adapters
Ams adaptersAms adapters
Ams adapters
 
Phoenix for Rails Devs
Phoenix for Rails DevsPhoenix for Rails Devs
Phoenix for Rails Devs
 
Construction Techniques For Domain Specific Languages
Construction Techniques For Domain Specific LanguagesConstruction Techniques For Domain Specific Languages
Construction Techniques For Domain Specific Languages
 
Rails 4.0
Rails 4.0Rails 4.0
Rails 4.0
 
JS-05-Handlebars.ppt
JS-05-Handlebars.pptJS-05-Handlebars.ppt
JS-05-Handlebars.ppt
 
Writing RESTful web services using Node.js
Writing RESTful web services using Node.jsWriting RESTful web services using Node.js
Writing RESTful web services using Node.js
 
Rails Engine | Modular application
Rails Engine | Modular applicationRails Engine | Modular application
Rails Engine | Modular application
 
IOC + Javascript
IOC + JavascriptIOC + Javascript
IOC + Javascript
 
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
Schema webinar
Schema webinarSchema webinar
Schema webinar
 
08 ajax
08 ajax08 ajax
08 ajax
 
Rail3 intro 29th_sep_surendran
Rail3 intro 29th_sep_surendranRail3 intro 29th_sep_surendran
Rail3 intro 29th_sep_surendran
 
AEM Sightly Deep Dive
AEM Sightly Deep DiveAEM Sightly Deep Dive
AEM Sightly Deep Dive
 
RequireJS
RequireJSRequireJS
RequireJS
 

More from Visual Engineering

Workshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSWorkshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJS
Visual Engineering
 
Workshop iOS 4: Closures, generics & operators
Workshop iOS 4: Closures, generics & operatorsWorkshop iOS 4: Closures, generics & operators
Workshop iOS 4: Closures, generics & operators
Visual Engineering
 
Workshop iOS 3: Testing, protocolos y extensiones
Workshop iOS 3: Testing, protocolos y extensionesWorkshop iOS 3: Testing, protocolos y extensiones
Workshop iOS 3: Testing, protocolos y extensiones
Visual Engineering
 
Workshop iOS 2: Swift - Structures
Workshop iOS 2: Swift - StructuresWorkshop iOS 2: Swift - Structures
Workshop iOS 2: Swift - Structures
Visual Engineering
 
Workhop iOS 1: Fundamentos de Swift
Workhop iOS 1: Fundamentos de SwiftWorkhop iOS 1: Fundamentos de Swift
Workhop iOS 1: Fundamentos de Swift
Visual Engineering
 
Workshop 24: React Native Introduction
Workshop 24: React Native IntroductionWorkshop 24: React Native Introduction
Workshop 24: React Native Introduction
Visual Engineering
 
Workshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux AdvancedWorkshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux Advanced
Visual Engineering
 
Workshop 21: React Router
Workshop 21: React RouterWorkshop 21: React Router
Workshop 21: React Router
Visual Engineering
 
Workshop 18: CSS Animations & cool effects
Workshop 18: CSS Animations & cool effectsWorkshop 18: CSS Animations & cool effects
Workshop 18: CSS Animations & cool effects
Visual Engineering
 
Workshop 15: Ionic framework
Workshop 15: Ionic frameworkWorkshop 15: Ionic framework
Workshop 15: Ionic framework
Visual Engineering
 
Workshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IWorkshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte I
Visual Engineering
 
Workshop 11: Trendy web designs & prototyping
Workshop 11: Trendy web designs & prototypingWorkshop 11: Trendy web designs & prototyping
Workshop 11: Trendy web designs & prototyping
Visual Engineering
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
Visual Engineering
 
Workshop 9: BackboneJS y patrones MVC
Workshop 9: BackboneJS y patrones MVCWorkshop 9: BackboneJS y patrones MVC
Workshop 9: BackboneJS y patrones MVC
Visual Engineering
 
Workshop 7: Single Page Applications
Workshop 7: Single Page ApplicationsWorkshop 7: Single Page Applications
Workshop 7: Single Page Applications
Visual Engineering
 
Workshop 6: Designer tools
Workshop 6: Designer toolsWorkshop 6: Designer tools
Workshop 6: Designer tools
Visual Engineering
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
Visual Engineering
 
Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.
Visual Engineering
 

More from Visual Engineering (18)

Workshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSWorkshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJS
 
Workshop iOS 4: Closures, generics & operators
Workshop iOS 4: Closures, generics & operatorsWorkshop iOS 4: Closures, generics & operators
Workshop iOS 4: Closures, generics & operators
 
Workshop iOS 3: Testing, protocolos y extensiones
Workshop iOS 3: Testing, protocolos y extensionesWorkshop iOS 3: Testing, protocolos y extensiones
Workshop iOS 3: Testing, protocolos y extensiones
 
Workshop iOS 2: Swift - Structures
Workshop iOS 2: Swift - StructuresWorkshop iOS 2: Swift - Structures
Workshop iOS 2: Swift - Structures
 
Workhop iOS 1: Fundamentos de Swift
Workhop iOS 1: Fundamentos de SwiftWorkhop iOS 1: Fundamentos de Swift
Workhop iOS 1: Fundamentos de Swift
 
Workshop 24: React Native Introduction
Workshop 24: React Native IntroductionWorkshop 24: React Native Introduction
Workshop 24: React Native Introduction
 
Workshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux AdvancedWorkshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux Advanced
 
Workshop 21: React Router
Workshop 21: React RouterWorkshop 21: React Router
Workshop 21: React Router
 
Workshop 18: CSS Animations & cool effects
Workshop 18: CSS Animations & cool effectsWorkshop 18: CSS Animations & cool effects
Workshop 18: CSS Animations & cool effects
 
Workshop 15: Ionic framework
Workshop 15: Ionic frameworkWorkshop 15: Ionic framework
Workshop 15: Ionic framework
 
Workshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IWorkshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte I
 
Workshop 11: Trendy web designs & prototyping
Workshop 11: Trendy web designs & prototypingWorkshop 11: Trendy web designs & prototyping
Workshop 11: Trendy web designs & prototyping
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
Workshop 9: BackboneJS y patrones MVC
Workshop 9: BackboneJS y patrones MVCWorkshop 9: BackboneJS y patrones MVC
Workshop 9: BackboneJS y patrones MVC
 
Workshop 7: Single Page Applications
Workshop 7: Single Page ApplicationsWorkshop 7: Single Page Applications
Workshop 7: Single Page Applications
 
Workshop 6: Designer tools
Workshop 6: Designer toolsWorkshop 6: Designer tools
Workshop 6: Designer tools
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
 
Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.
 

Recently uploaded

Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
lorraineandreiamcidl
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
Globus
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
abdulrafaychaudhry
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Globus
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
ShamsuddeenMuhammadA
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Globus
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
Matt Welsh
 

Recently uploaded (20)

Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
 

Workshop 17: EmberJS parte II

  • 1. Front End Workshops EmberJS - In Depth Marc Torrent & Mario García mgarcia@visual-engin.com mtorrent@visual-engin.com
  • 2. In previous workshops of EmberJS...
  • 3. Remember the BIG PICTURE ember-cli Router Routes application.js Models Templates Components Ember-Data Controllers S E R V I C E S
  • 4. Ember Data - Adapters & Serializers
  • 5. Ember Data Application Route/Controller/Component Can be thought as a read-through cache Single store - Central repository of models in your application Beware of cache-backend desynchronization! Ember Data
  • 6. Communication with backend How we access data DS.Adapter DS.Serializer As of Ember Data 2.0, the default Adapter and Serializer follow JSON API format. REST API Ember Ember Data Format of the data
  • 7. JSON API Specification Content-Type: application/vnd.api+json Top level attribute “data” Attribute names are dasherized Attribute “type” should be pluralized It’s about the data...
  • 8. JSON API Specification ..but also about the end points! Action HTTP Verb URL Response status* Find GET /articles/123 200 - Successful 404 - Not found Find All GET /articles 200 - Successful 404 - Not found Update PATCH /articles/123 200 - Successful 204 - No Content Create POST /articles 201 - Created 204 - No Content Delete DELETE /articles/123 200 - Successful 204 - No Content *More response statuses are possible. See the complete specification at http://jsonapi.org/format/
  • 9. Adapters Extend/build your own adapters to fit your needs! Priority rules apply between adapters! DS.Adapter DS.JSONAPIAdapter DS.RESTAdapter How to communicate with backend
  • 10. Customize your adapter (1 of 3) // app/adapters/application.js export default DS.JSONAPIAdapter.extend({ host: 'https://api.example.com', namespace: 'api/v1' }); store.findRecord('post', 1) GET request to http://api.example.com/api/v1/posts/1 Host customization - Endpoint path customization store.findAll('person') GET request to http://api.example.com/api/v1/people store.findAll('user-profile') GET request to http://api.example.com/api/v1/user-profiles
  • 11. Customize your adapter (2 of 3) Type path customization // app/adapters/application.js export default DS.JSONAPIAdapter.extend({ pathForType(type) { return Ember.String.underscore(type); } }); store.findRecord('post', 1) GET request to /post/1 store.findAll('person') GET request to /person store.findAll('user-profile') GET request to /user_profile Headers customization // app/adapters/application.js export default DS.JSONAPIAdapter.extend({ headers: { 'API_KEY': 'secret key', 'ANOTHER_HEADER': 'Some header value' } });
  • 12. Customize your adapter (3 of 3) Pluralization customization Ember Inflector at your rescue! Allows definition of irregular and uncountable pluralizations Houston... Our API REST serves at the following endpoints: ➔ /formulae (instead of the regular form /formulas) ➔ /advice (instead of the pluralized form /advices) ...do we have a PROBLEM?
  • 13. Serializers DS.Serializer DS.JSONAPISerializer DS.JSONSerializer DS.RESTSerializer Extend/build your own serializers to fit your needs! Priority rules apply between serializers! Define the format of the data
  • 14. Serializing data sent to backend Customize your serializer (1 of 4) // JSON generated by Ember Data { "data": { "attributes": { "name": "Product", "amount": 100, "currency": "SEK" }, "type": "product" } } // But server expects... { "data": { "attributes": { "name": "Product", "cost": { "amount": 100, "currency": "SEK" } }, "type": "product" } } Change the format of the data sent to backend with the serialize() hook.
  • 15. Normalizing data received from backend Customize your serializer (2 of 4) // Server response { "id": "1", "body": "A comment!", "date": { "offset": "GMT+0200 (CEST)", "value": "Tue Apr 05 2016" } } // But Ember Data expects... { "id": "1", "body": "A comment!", "offset": "GMT+0200 (CEST)", "value": "Tue Apr 05 2016" } Change the format of the data received from backend with the normalizeResponse() hook.
  • 16. Identifier Customize your serializer (3 of 4) Specify your resource identifier key through primaryKey property export default DS.JSONSerializer.extend({ primaryKey: '_id' }); Attribute names If the JSON payload does not match your Ember model attribute names... // app/models/person.js export default DS.Model.extend({ lastName: DS.attr('string') }); // app/serializers/person.js export default DS.JSONAPISerializer.extend({ attrs: { lastName: 'lastNameOfPerson' } });
  • 17. Custom transforms Customize your serializer (4 of 4) Use custom transforms if the server sends data that does not fit any Ember Data built-in attributes (string, number, boolean and date) A custom transform should implement the serialize() and deserialize() Once implemented, it can be used as a regular type of attribute
  • 19. Routing - Implicit routes ember g route users ember g route users/edit application application-loading application-error index index-loading index-error users users-error users/index users-loading users/edit *All routes have its .hbs associated templates loading error users/edit-error users/edit-loading users/index-loading users/index-error users/loading users/error
  • 20. Routing - Serve more than one model Promises, promises, promises! Ember.RSVP.hash resolves when all its promises parameters resolve Be extra careful when using hash in the model() hook in cases where the hook is not executed* *See http://stackoverflow.com/questions/20521967/emberjs-how-to-load-multiple-models-on-the-same-route Alternatively, you can use route nesting to load multiple models More info in http://emberigniter.com/load-multiple-models-single-route/
  • 21. Routing - Rendering a specific template // app/routes/posts/new.js export default Ember.Route.extend({ renderTemplate() { this.render('posts/form'); } }); It is possible to render a specific template through the renderTemplate() hook. DRY*!!!!! *Don’t Repeat Yourself // app/routes/posts/edit.js export default Ember.Route.extend({ renderTemplate() { this.render('posts/form'); } });
  • 22. Routing - Preventing and retrying transitions Invoke transition.abort() to immediately abort the current transition Store the transition object and re-attempt invoking transition.retry() Every transition attempt fires the willTransition action on the current active routes, starting with the leaf-most route Ember Router passes a transition object to various hooks on the involved routes export default Ember.Route.extend({ beforeModel(transition) {}, model(params, transition) {}, afterModel(model, transition) {} });
  • 23. Routing - Loading routes When navigating to /users route, Ember will try to find loading templates*: users-loading loading or application-loading The router pauses transitions until the promises returned from beforeModel, model and afterModel hooks fulfill An intermediate transition into a loading substate happens immediately The URL won’t be updated on the loading transition *See https://github.com/emberjs/ember.js/issues/12367 A loading event will be fired on that route
  • 24. Routing - Error routes When an error occurs navigating to /users, Ember will try to find templates*: users-error error or application-error Analogous approach to loading substates in the case of errors An intermediate transition into an error substate happens in case of thrown error or rejected promise The URL won’t be updated on the error transition *See https://github.com/emberjs/ember.js/issues/12367 An error event will be fired on that route
  • 25. Routing - Query params {{#link-to "episodes" (query-params filter="simp")}}Episodes{{/link-to}} transitionTo('episodes', { queryParams: { filter: 'simp' }}); Query params are declared on route-driven controllers Use controller’s queryParams property to bind query params and URL Query params to backend Query params in frontend transitionTo link-to helper store.query('episodes', { filter: 'simp' });
  • 27. ➢ Data Binding in template attributes ➢ Links ➢ Actions ➢ Input Helpers ➢ Write your own helpers
  • 28. Data Binding in Templates Controller’s Properties <div class=”_tomster”> <img src={{tomster.img}} width=100> </div> DOM Attributes <div class=”_tomster”> <input type=”checkbox” disabled={{tomster.disabled}}> <img src={{tomster.img}} width=100> </div> Collections {{#each cartoons as |cartoon|}} <div class=”_cartoon”> <input type=”checkbox” disabled={{cartoon.disabled}}> <img src={{cartoon.img}} width=100> </div> {{/each}}
  • 29. Links: {{#link-to }} A helper for links in our application without the need of using anchors and href. Router.map( function() { this.route(‘about’); this.route(‘cartoons’, function() { this.route(‘cartoon’, {path: ‘/:cartoon_id’}); }); }); <ul> {{#each model as |cartoon|}} <li>{{#link-to "cartoons.cartoon" cartoon}}{{cartoon.name}}{{/link-to}} </li> {{/each}} </ul> <ul> <li><a href="/cartoon/1">Columbus Tomster</a></li> <li><a href="/cartoon/2">LTS Tomster</a></li> </ul>
  • 30. Links: {{#link-to }} - Multiple Segments We pass the model to the most inner nested route. The model() hook won’t be called on routes where we specify the model through the link-to. Router.map( function() { this.route(‘cartoons’, function() { this.route(cartoon, {path: ‘/:cartoon_id’}, function() { this.route(‘specs’); this.route(‘spec’, {path: ‘/specs/: spec_id’}); }); }); }); <ul> {{#each cartoons as |cartoon|}} {{#each cartoon.specs as |spec|}} <li>{{#link-to "cartoons.cartoon. spec" spec}}{{spec.name}}{{/link-to}} </li> {{/each}} {{/each}} </ul>
  • 31. Links: The Route that went away… (I) Be careful with the structure of the templates and routes and beware of models that you pass into the routes
  • 32. Links: The Route that went away… (II) Be careful with the structure of the templates and routes and beware of models that you pass into the routes Keep an eye on how you distribute your outlets and the relation between index.hbs and the current template in our nested route. Let’s see it in action! Now you tell me what should I place in the router - routes - templates and link-to
  • 33. Actions 1. Template helper for binding a DOM Event with a Controller/Route/Component. 2. It can accept parameters such as Ember.Objects, Models or basic data structures. 3. You can also specify the type of event by using the “on” option 4. By default, actions prevent the default browser action on a DOM Element. To turn down this behavior, pass the option preventDefault=false
  • 34. Input Helpers {{input}} {{textarea}} 1. Template helper for <input> and <textarea> DOM Elements. 2. Forget about actions with inputs and use the the input helpers as EmberJS provides out of the box 2-way data-binding 3. Pass HTML and HTML5 attributes 4. Use it also with radio and checkboxes
  • 35. Write Your Own Helpers Custom template helpers for your own needs. Keep an eye on addons to see if someone else has already written the helper you need. ember generate helper i18n That file should export a function wrapped with Ember.Helper. helper() The function receives a bundle destination as string as the first parameter (params[0]) and the key to look for as the second parameter (params[1]) To pass multiple arguments to a helper, add them as a space- separated list after the helper name Use named Parameters to make behavior of helpers configurable export function i18n([bundle, key], {lang, toUpperCase}) { let resource = dictionary[bundle][key], translation = lang? resource[lang] : resource[DEFAULT_LANG]; return toUpperCase? translation. toUpperCase() : translation; } export default Ember.Helper.helper(i18n); <p>{{i18n "catalog" "category" lang="es"}}</p> <p>{{i18n "catalog" "category"}}</p> <p>{{i18n "catalog" "category"}}</p> <p>{{i18n "catalog" "product" toUpperCase="true"}}</p>
  • 37. Routes Controllers Components Helpers ... Service Persistent Object that can be accessed for all the application modules though: Ember.inject.service()
  • 38. Services - For What? Services are useful for features that require shared state or persistent connections. User/session authentication Geolocation Web Sockets Server-sent events or notifications Server-backed API calls that may not fit Ember Data Third-party APIs Logging Internationalization
  • 39. Services - and How can I use it? Create the Service: ember generate service i18n Services must extend the Ember.Service base class: Ember.Service.extend({}); Basic Service Advanced Service Use the service in an Ember Object or inherited: i18n: Ember.inject.service() The Service will be injected by the same name we are assigning to a variable (i18n) USE YOUR IMAGINATION, EVERYTHING IS POSSIBLE!
  • 41. LA JOYA DE LA CORONA AND ROUTABLE COMPONENTS ARE COMING!!
  • 42. Components: Definition ➢ A reusable partial view (template with Handlebars) with controller that can be combined with other components and contain other components. ❖ Components are used in route templates. ❖ They have a specific life cycle and can handle actions of their template and also pass actions to their containing components, routes and controllers. ❖ At this moment components are not routable but soon they will become routable and then, controllers will disappear. ❖ At this moment, EmberJS 2.4.0, All components need to be included inside a template route that, by definition, has a Shim Controller. ❖ You can think of Components as widgets that are reusable through all our application and that expose a template helper per usage. ember generate component my-component → components/my-component.js → templates/my-component.hbs <ul> <li>{{my-component}}</li> </ul>
  • 43. Components: Passing Properties ➢ Pass Properties TOP - DOWN to components. Always from route templates or other components to the destination component. export default Ember.Route.extend({ model() { return this.store.findAll('actor'); } }); <ul> {{#each model as |actor|}} <li>{{actor-component actor=actor}}</li> {{/each}} </ul> <div>{{actor.name}}<span {{action "toggleSection"}} style="margin-left: 5px;">{{more}} </span></div> {{#if showImage}} <div><img src="{{actor.img}}" width="200px"></div> {{/if}}
  • 44. Components: Wrapping Content ➢ Let the developer use your component by passing custom content into it. ○ The template using your component will pass an html block inside the component ○ The component MUST define the {{yield}} expression in its template ○ The component MUST be used in block form: {{#my-component}}... {{/my-component}} <div>{{yield}}<span {{action "toggleSection"}}>{{more}}</span> </div> {{#if showImage}} <div> <img src="{{actor.img}}" width="200px"> </div> {{/if}} <ul> {{#each model as |actor|}} <li>{{#actor-component actor=actor}} <p>{{actor.name}}</p> {{/actor-component}} </li> {{/each}} </ul>
  • 45. Components: LifeCycle ➢ Access to hooks when the component is going to be rendered or destroyed. ➢ It enables you to: ○ Direct DOM manipulation ○ Listening and responding to browser events ○ Using 3rd party JavaScript libraries in your Ember app Initial Rendering: 1 init 2 didReceiveAttrs 3 willRender 4 didInsertElement 5 didRender Re-Rendering: 1 didUpdateAttrs 2 didReceiveAttrs 3 willUpdate 4 willRender 5 didUpdate Component Destroy: 1 willDestroyElement 2 willClearRender 3 didDestroyElement 6 didRender
  • 46. Components: Data Down - Actions Up ➢ Keep the idea that state (properties) always travels in one direction: TOP - DOWN. ➢ Instead, event handling (actions) always travel in the opposite direction: BOTTOM-UP. ➢ Components and Controllers can handle actions from their contained Components. See it as a data synchronization hub. export default Ember.Component.extend({ actions: { toggleSection() { this.toggleProperty('showImage'); this.get('onSelected')(this); } } export default Ember.Controller.extend({ actions: { sectionShown(selectedActor) { this.set('selectedActor', selectedActor); } } }); {{actor-component actor=actor onSelected=(action "sectionShown")}}
  • 47. Components: Transversal Communication ➢ In some situations components can not be on the same parent. ➢ We need a data-layer and a BUS using Pub-Sub ➢ For this purpose, use a Service extending Ember.Evented export default Ember.Component.extend({ Appointment: Ember.inject.service(), actions: { complete() { this.get(‘appointment’).trigger(‘complete’); } } }); export default Ember.Component.extend({ appointment: Ember.inject.service(), willRender() { this.get(‘appoinment’).on(‘complete’, this, ‘onComplete’); }, onComplete() { // Do Something } });
  • 48. Integration with 3rd party libraries
  • 49. Integrate into the Ember using the asset manifest file ember-cli-build.js Integration with 3rd party libraries If an Ember addon exists... Install via Ember CLI and you are ready to go! Front-end dependencies can be installed through Bower Package Manager Other assets can (and should) just be placed in the vendor folder of the project app.import({ development: 'bower_components/moment.js', production: 'bower_components/moment.min.js' }); app.import('vendor/amd.js', { exports: { 'amd': ['raw', 'request'] } }); Globals AMD Modules
  • 50.
  • 51. Remember the BIG PICTURE ember-cli Router Routes Models Templates Components Ember-Data Controllers S E R V I C E S
  • 52.
  • 53. Thanks for your time! Do you have any questions?