A few months after I started working with Ember.js & Ember Data at my new job we began a project to upgrade both. There were parts that were a breeze and others that were quite tricky. This talk walks you through some of the challenges we faced and how we solved them as well as how we began to prepare for the Ember 2.x architectural shift. Hopefully this talk will help save you some time when you decide to upgrade your Ember web application.
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
In The Trenches With Tomster, Upgrading Ember.js & Ember Data
1. In The Trenches With Tomster,
Upgrading Ember.js & Ember Data
Stacy London
@stacylondoner
May 2016
2. In The Trenches With Zoey,
Upgrading Ember.js & Ember Data
Stacy London
@stacylondoner
3. @stacylondoner
Who Am I?
• mostly a front-end engineer, artist, musicophile, &
traveler
• head up front-end engineering at ShoreTel’s
Milwaukee, WI office
• co-organizer of @mkejs, TA for @milwaukeegdi
• 1st web adventure was with geocities in 1997
• working with ember.js & ember-data for ~1 year
3
5. @stacylondoner
What is Ember.js?
• “A framework for creating
ambitious web applications”
• an open source single page web
application (SPA) framework
• Routes, Models, Components,
Controllers, Services
• Model View Controller (MVC) —>
Model Component (MC)
• common idioms and best practices
are incorporated into the framework
so you can focus on building your
app and not reinventing the wheel
5
6. @stacylondoner
What is Ember.js?
• convention over configuration
• developer productivity by providing a complete dev stack
• pluggable architecture (ember add-ons)
• stability without stagnation - big focus on backwards
compatibility while still innovating
• future web standards in mind - early adopter of promises,
web components, & ES6. Yehuda Katz (Ember co-
founder) is on the TC39 committee helping to set the future
direction of JavaScript
6
7. @stacylondoner
Ember CLI
• dev server with live reload
• complete testing framework
• provides generators for scaffolding (folder & file structure)
• dependency management
• ES6 modules
• ES6 syntax support + Babel
• asset management/build pipeline (combining, minifying,
versioning)
7
8. @stacylondoner
Ember Data
• data-persistence library
• maps client-side models (in a local data store) to
server-side data
• can load & save records and their relationships
without any configuration via RESTful JSON API
• model.save(); —> AJAX POST or PUT to your API
8
13. @stacylondoner
Our Ember App
• 69K lines of code
• 7K lines of LESS
54K lines of JS
8K lines of HTML (.hbs)
• 134 routes
104 models
152 controllers
171 components
292 templates
** numbers are approximate and include subdirectory folders
13
15. @stacylondoner
Ember Upgrades
• follows semantic versioning (semver)
• breaking changes introduced at major versions
• new features / bug fixes at dot releases
• 6 week release cycle
• all major 2.x features were introduced early and
spread across several releases to avoid massive
upgrade issues
15
16. @stacylondoner
Long Term Support (LTS) Release
• Ember 2.4 is the first LTS
release
• good if you can’t upgrade
every 6 weeks
• bug fixes for 36 weeks
• security fixes for 60 weeks
• every 4th release will be
LTS
16
17. @stacylondoner
Ember Architecture 1.x
• encouraged a Model-View-Controller-Route
architecture
• since then the industry has converged on a Model-
Component-Route pattern, which is what Ember 2.x
embraces
17
19. @stacylondoner
Ember 2.x
• 2.0 was mostly about removing deprecated code
• One way data flow by default. Data down, actions
up (DDAU). Similar to React.js.
• Glimmer rendering engine speed improvements
(DOM diff algorithm similar to React.js)
• Fastboot for progressive web apps
19
22. @stacylondoner
Upgrading Tips
• Apply each upgrade incrementally
• Don’t jump from 1.10.x to 2.4.x
• Recommend you don’t run the init part of the
upgrade directly on your project.
• Create a new dummy ember app at the new
version and compare to your project.
22
25. @stacylondoner
Deprecation Warnings
• Ember will warn you ahead of new versions that something
is going to be deprecated by detecting use of it and then
outputting a warning message in the browser console.
• http://emberjs.com/deprecations/v1.x/
DEPRECATION: Using `{{view}}` or any path based on it
(‘some-template.hbs' @ L84:C16) has been deprecated.
[deprecation id: view.keyword.view] See http://emberjs.com/
deprecations/v1.x#toc_view-and-controller-template-keywords
for more details.
25
26. @stacylondoner
1.10 > 1.13: Remove Views
• remove all Views and replace with Components
• some Ember add-ons still were using Views so
needed those to upgrade before moving to Ember
2.x where Views were removed
• or you could include this to add Views back until
all add-ons are upgraded - https://github.com/
emberjs/ember-legacy-views
26
27. @stacylondoner
1.10 > 1.13: Remove Views
• components are isolated (scoped) so actions don’t
automatically bubble up
• had to refactor by registering the action we want to bubble
out of a component in the template calling the component
innerAction=“outerAction”
• using closure actions is a more elegant way to accomplish
this that we learned about later ;).
https://dockyard.com/blog/2015/10/29/ember-best-
practice-stop-bubbling-and-use-closure-actions
27
32. @stacylondoner
1.10 > 1.13: Remove bind-attr helper
• DEPRECATION: The `bind-attr` helper
(‘myTemplate.hbs' @ L2:C6) is deprecated in favor of
HTMLBars-style bound attributes.
<div {{bind-attr
class="noPrevPage:disabled :card-icon-wrapper"}}
{{action "prevPage"}}>
<!--becomes-->
<div class="{{if noPrevPage 'disabled'}} card-
icon-wrapper” {{action "prevPage"}}>
32
33. @stacylondoner
1.10 > 1.13: Ember Watson
• some of the available changes were extremely
tedious to do and couldn’t be globally found/replaced
• ember watson to the rescue!
https://github.com/abuiles/ember-watson
• biggest help was to convert computed properties and
observers to not use prototype extensions
• NOTE: It’s not required that you remove prototype extensions as part of the upgrade.
Decorators are coming so you may want to wait to switch until then. This just felt nicer
for reading code until then.
https://github.com/emberjs/guides/pull/110
33
34. @stacylondoner
1.10 > 1.13: Ember Watson
isAvailable: function() {
//code here
}.property('currentPresence'),
// watson automatically adjusted the code to:
isAvailable: Ember.computed('currentPresence', function() {
//code here
}),
34
35. @stacylondoner
1.10 > 1.13: Ember Watson
sourceListObserver: function() {
//code here
}.observes('sourceList'),
// watson automatically adjusted the code to:
sourceListObserver: Ember.observer('sourceList', function() {
//code here
}),
35
36. @stacylondoner
Ember Data
• Our RESTful API is written in Python using Tastypie
which is a web service API framework for Django.
• The ember-data default RESTAdapter does not
follow the conventions used in django-tastypie.
• Our Adapter & Serializers do quite a bit of work to
transforms the payloads and are based on https://
github.com/escalant3/ember-data-tastypie-adapter/
36
37. @stacylondoner
Ember Data 1.10 > 1.13
• sampled find methods meant touching a lot of our
code to replace store.find, store.all, and
store.getById with this more consistent API:
37
38. @stacylondoner
Ember Data 1.10 > 1.13
• API naming changes caused a bit of refactoring
• rollback renamed to rollbackAttributes
• isDirty renamed to hasDirtyAttributes
38
39. @stacylondoner
Ember Data - RESTAdapter
• needed to override ajaxOptions to make sure traditional
= true (which removes the [] from array parameters)
• needed to override handleResponse and
normalizeErrorResponse to map any error information in
the payload so that `reason` wasn’t empty when an issue
happened with saving/retrieving data
model.save().then(function() {
// success
}, function(reason) {
// failure
});
39
40. @stacylondoner
Ember Data - RESTSerializer
• Helper that converts a django-tastypie URI into an id for
ember-data use
• Conversions of attribute names to use underscores
• normalizeId was removed in Ember Data 2.x but we
still need to be able to convert from resource URIs into
Ids so just had to remove call to _super.
• since we have customized our serializer we needed to
set this flag as part of upgrading to 1.13.x:
isNewSerializerAPI: true
40
41. @stacylondoner
Ember Data - Model Helper
• in order to do do dirty checks and rollbacks on models with
complex relationships (hasMany, belongsTo) we have to re-
open the model and add additional logic
• this logic basically stores the original relationships on load
of the model so that they can be used later for rollback/dirty
checking
• now when you do model.rollback() it will rollback everything
including hasMany and belongsTo relationships
• http://stackoverflow.com/questions/14685046/how-to-rollback-
relationship-changes-in-emberdata/27184207#27184207
41
42. @stacylondoner
Ember Data 2.x
• JSON API Adapter & Serializer become the default
• this still does not follow the conventions used in
django-tastypie so we are not taking advantage
of that
• In Ember Data 2.0 relationships will be
asynchronous by default
42
44. @stacylondoner
Issues / Struggles - Versions
• Should your version of ember-data, ember-cli and ember.js
be the same? This is not very clear in the documentation.
Answer: Yes (but doesn’t have to).
• “Ember-Data and Ember CLI will be versioned in
lockstep with Ember itself"
http://emberjs.com/blog/2015/08/13/ember-2-0-
released.html#toc_ember-2-x-themes
• Technically any version of Ember CLI can work with any
version of Ember.js. You can stay on Ember.js 1.x and
upgrade to the latest Ember-CLI if you figure out the
correct dependencies.
44
45. @stacylondoner
Issues / Struggles - Documentation
• Documentation hasn’t always been kept up to date
with released versions so it was sometimes hard to
know if you were doing something in the right way.
• Now there is a dedicated team and direction that
no new features will be added to the Ember 2.0
release channel without accompanying
documentation.
45
46. @stacylondoner
Ember Community
• If you run into an issue with a version you are
upgrading to you can log an issue on GitHub. My
experience has been really positive (people are
nice and helpful).
• e.g. classNames on components were being
output twice in the DOM in 1.13.8. Logged an
issue and it was resolved quickly.
https://github.com/emberjs/ember.js/issues/12146
46
47. @stacylondoner
Looking Ahead
• routable components (then we can remove
controllers)
• angle bracket components (for true one-way data
flow)
• use Fastboot for progressive web app
• 2.x deprecations
http://emberjs.com/deprecations/v2.x/
47
48. @stacylondoner
Angle Bracket Components
{{!-- title is a mutable two-way binding --}}
{{my-component title=model.name}}
{{!-- title is just an (immutable) value --}}
<my-component title={{model.name}} />
48
49. @stacylondoner
Other Recommendations
content > model
• There was some confusion about if you should use
content or model. Content was used across our
codebase from implementing early beta versions.
Use model.
• Per Yehuda “People should use model as the
public API and things should work. If they do not in
some case, it's a bug and the bug should be
opened.”
https://github.com/emberjs/ember.js/issues/2007
49
50. @stacylondoner
Other Recommendations
Liquid Fire
• If you do any sort of animation with JavaScript you should move
that into Liquid Fire so that you’ll have promise-based transitions.
• https://github.com/ember-animation/liquid-fire
• http://ember-animation.github.io/liquid-fire/
• This is critical if you are using the Ember test suite with
acceptance tests so that the ember run loop is cleaned up
appropriately in between tests.
• A good use case is transitioning modals. If you use Bootstrap
modals and the associated JS that goes with it to animate you’ll
have a bad time.
50
51. @stacylondoner
Resources
• Ember Blogs - notes about each release
http://emberjs.com/blog/2015/08/13/ember-2-0-
released.html
• Ember CLI Upgrade docs
http://ember-cli.com/user-guide/#upgrading
• compare two versions to see what’s changed
https://github.com/ember-cli/ember-new-output/compare/
• deprecation workflow - hide deprecation noise so you can
work through one deprecation fix at a time
https://github.com/mixonic/ember-cli-deprecation-workflow
51