My experience with migrating from Ember.js RC7 to 1.0.0

I started the migration of a small inhouse project from RC7 to 1.0.0. Below is an overview of the areas I had to work on (breaking changes and resolution of deprecated areas). I hope this overview is useful for others. Do not hesitate to post your own experiences as a comment on this post.

1. Error when using Ember.js 1.0.0 in combination with Ember Data 0.13

When you have a project in which you use the combination of Ember.js 1.0.0 with Ember Data 0.13, you will get the following error:

Uncaught Error: Ember.State has been moved into a plugin: https://github.com/emberjs/ember-states

Ember itself does not use Ember.State, but Ember Data 0.13 requires it.

Solution: include the Ember State library (https://github.com/emberjs/ember-states).

As of Ember Data 1.0.0 Beta, Ember.State is no longer needed.

See ember.js - Ember 1.0.0: Ember.State has been moved into a plugin: https://github.com/emberjs/ember-states - Stack Overflow for more info.

2. Documentation recommends using Ember Data 0.14

Although the documentation recommends to use Ember Data 0.14 (and no longer 0.13), there is no link to the 0.14 build version on http://builds.emberjs.com/ .

Solution: build the lib yourself or stick to 0.13

You could also start looking into a migration to Ember Data 1.0.0 Beta, which is a reboot of Ember data and will require some profound changes.

3. Deprecation: Application.resolver should be Application.Resolver

I use Application.Resolver to dynamically load hbs templates. Simple change of Application.resolver to Application.Resolver was needed.

4. Deprecation: Methods implemented directly on controllers should be put under ā€˜actionsā€™ object

In most of my controllers, I have a number of methods directly implemented on the controller. This will result in the warning:

DEPRECATION: Action handlers implemented directly on controllers are deprecated in favor of action handlers on an `actions` object

Solution: Define the actions inside the actions hash of the controller:

App.ApplicationController = Em.ObjectController.extend({
  actions : {
   // your actions here
  }       
});

Important: please note that after this change, actions can no longer be invoked directly, thus:

this.controllerFor('category.edit').save();

Should be changed into:

this.controllerFor('category.edit').send("save");

The above required a lot of changes in my code; very sensitive to mistakes ā€¦

5. Deprecation: Action handlers contained in events at route level should be put under ā€˜actionsā€™ object

If you use the events hash of the route, then change it to actions:

events: { xxx }  

Should be changed into:

actions: { xxx } 

6. JQuery version

It is unclear to me which version of JQuery is recommended. In general, a compatibility overview of library dependencies should be welcome ā€¦

7. Ember Data 1.0.0 Beta

Ember Data 1.0.0 beta is a reboot of Ember data 0.13/0.14. There is a good document describing the changes (and there are a lot) ā€¦ See: https://github.com/emberjs/data/blob/master/TRANSITION.md

So far, I have managed to read data via the RESTAdapter and to save a simple record. There are however a number of open questions I have before being able to further migrate the code to Ember Data 1.0.0. The questions are listed below (posted on stackoverflow). Hope somebody can help.

I will complete this overview as soon as I get Ember Data 1.0.0 operational.

All in all, migration from RC7 to 1.0.0 went smooth !
Migration to Ember Data 1.0.0 is more profound and I hope to complete this soon.

Marc

6 Likes

Awesome, solved all my problems!

One last thing, my demo app had a Store specifying the fixtureAdapter like this:

App.Store = DS.Store.extend({
    adapter: 'DS.FixtureAdapter'
});

Everything was kinda broken, I fixed the problem by removing the quotes. So like this:

App.Store = DS.Store.extend({
    adapter: DS.FixtureAdapter
});

Worked also with the LSAdapter :slight_smile:

1 Like

This only applies to methods that are used as action handlers. Methods that are called otherwise (e.g. directly from application code can still be defined and called directly on the controller.

2 Likes

One thing Iā€™ve found (that I couldnā€™t see documented anywhere) is that Ember.TextField and Ember.TextArea have changed from extending views to now extending components, meaning that if you want to call a componentā€™s controller, you have to call this.get('targetObject') instead of this.get('controller')

(Found inside this commit).

1 Like

One of the biggest things that bite me was, ā€œUnconsumed computed properties do not trigger observersā€. At first it seemed like a low impacting change, but we have a lot of controller mixins in our application that provide additional functionality. We had started to use Ember.computed.alias to help alias properties on the controller that are consumed by the mixin. Because we used Ember.computed.alias, it ends up falling into this scenario and we got burned quite a bit.

Here is an actual example: http://jsbin.com/ucanam/885/edit . Uncomment the _setupObserver function to see a demo.

So it seems for now, weā€™ll just add some silly functions that rely on .on('init') to setup these properties until we can phase this pattern out in our app. It gives me mixed feelings about this change overall. It feels a bit like the technical details of change have leaked into the API.

Any how, just wanted to share that!

Edit: Seems that the general use of Ember.computed.alias has caused a few headaches around this change. Just a warning to anyone using it.

i have some problem with routing and i cant solve theme : problem with routing

One of the things Iā€™m running into has to do with moving my functions into actions. The view was dynamically adding buttons based on the existence of functions. Like this.

{{#if view.cancel}}
    <button class="link" {{action "cancel" target="view"}}>Cancel</button>
{{/if}}

Thatā€™s because these actions may or may not be implemented on the view that inherits from it. However once I moved them under actions the only way Iā€™ve found so far is to do thisā€¦ which seems wrong.

{{#if view._actions.cancel}}
    <button class="link" {{action "cancel" target="view"}}>Cancel</button>
{{/if}}

This has been fixed and 0.14 is now available at Releases - Ember.js.

We run tests against jQuery 1.7 as well as the latest jQuery builds. I would recommend using the latest jQuery release if thereā€™s nothing preventing you.

One thing that broke for me was displaying the records a hasMany relationship in a view:

Model:

App.List = DS.Model.extend({
	listName : DS.attr( ),
	cards : DS.hasMany( 'card' )
});

Route:

App.ListsRoute = Ember.Route.extend({
	model: function() {
		return this.get( 'store' ).findAll( 'list' );
	}
});

View:

{{#each card in cards itemController="card"}}
    //always blank prob because the promise hasn't resolved?
{{/each}}

Does anybody in this discussion know how to get the card models to resolve before displaying them in the view?

Assertion failed: You tried to set adapter property to an instance of DS.Adapter, where it should be a name or a factory

For those who are getting this error, it seems moving to 1.0, you donā€™t need to create your adapater instance in your store.

App.Store = DS.Store.extend({ revision: 14, adapter: DS.LSAdapter.create() })

With

App.Store = DS.Store.extend({ revision: 14, adapter: DS.LSAdapter })

This should solve the above issue.

I ran into this problem with an observer not firing that when the watched property is set in the initializer: