EmberJS

Ember upgrade from 1.7.0 to 1.13.13

October 4, 2016 EmberJS No comments

EmberRelease Obviously there are general upgrade guides provided by Ember team and many fellow bloggers. This is just to document one of the experiences with upgrading from ember 1.7.0 to 1.13.13.

At the moment of this writing Ember latest stable version is 2.8. My team was one of the early adopters of Ember. I believe the team started incorporating it in late 2013, which is very soon after the 1.0 release. We went live with the version 1.7 at the beginning of 2015 and since that time we didn’t do any updates for “penny wise and pound foolish” reasons.

Upgrade itself was a bit of pain as it spread for couple of months. We allocated few days per sprint and at the same time continued developing new features the old way in other branches. Bad idea.

Another pain was that we adopted Ember Data while it was still beta. As a result we have custom code altering adapter’s and serializer’s behaviour. There are many breaking changes between beta versions of Ember Data, so using it while in beta was a very bad idea.

One of great things about being on Ember 1.13.13 version is that you are effectively on 2.0.0 version unless you have deprecation messages in your console. This also means that you can still release your application with some parts not being completely converted to the new way of doing things. ember.prod.js doesn’t generate warnings and works just fine. I really like the way Ember tries to make upgrading easy. Here is a nice write up on handling deprecations as of 2.3.0.

List of useful links:

Gotcha list:

This list is composed from notes I took so it is not very well organized and does not contain all of the items we had to fix.

When upgrading from 1.7 to 1.8

  • Update ember data to 1.0.0-beta.11 for compatibility and as a fix for “Ember Data cannot read property 'async' of undefined"
  • Replace pushObject with addRecord to fix “You looked up the relationship on a with id but some of the associated records were not loaded.”
  • This does not work and has to be rewritten Ember.Handlebars.helpers.render.call(this, name, contextString, options)
  • Use Ember.set() whenever there was controller.isNew property with some set

When upgrading from 1.8 to 1.10.1

  • Start using HTMLBars instead of Handlebars by incorporating ember-template-compiler
  • add stripBOM to grunt file… as template compiler includes those: template = template.replace(/\uFEFF/g, ''); // remove BOM
  • Fix HTML to be correct (closing tags, missing tbody, etc)
  • ember-data 1.0.0-beta.11 has bug in findQuery asserts => upgrade ember-data to 1.0.0.beta12
  • Remove //# sourceMappingURL=ember-data.js.map
  • Ensure models are generated with {async: false}
  • Remove code that works with MetamorphView. Fixes this: Assertion Failed: A fragment cannot be pushed into a buffer that contains content because of: view.createChildView(Ember._MetamorphView, {

When upgrading from 1.10.1 to 1.11.4

At this point you start to get tons of deprecation messages.

  • You attempted to access `someProperty` from `<App.SomeXyzController:ember2661>`, but object proxying is deprecated. Please use `model.someProperty` instead.
  • Convert this {{action bubbles=false preventDefault=false}} to this {{action "ok" "close" "cancel" bubbles=false preventDefault=false}}
  • Fix dynamic compilation of HTMLBars. Cannot call `compile` without the template compiler loaded. Please load `ember-template-compiler.js` prior to calling `compile`. Ember.HTMLBars.compile(submitHtmlTemplate); doesn’t produce a correct function to retrieve HTML. Can be solved as in this SO answer.
  • Using @each at the end of a computed key is deprecated and will not work in Ember 2.0
  • Replace Ember.Enumerable.mapProperty with mapBy
  • Replace Ember.Handlebars.helper with Ember.Helper.helper

When upgrading from 1.11.4 to 1.13.13

  • Rewrite code that uses itemController
  • Rewrite properties that have setter to the new computed syntax

I hope this comes in handy for you.


No comments


EmberJs Object deep copy by serialization/deserialization

April 8, 2014 EmberJS No comments

I had to implement copy functionality in our Ember application so it would allow to copy any section of data from parent source to target. In order for this to work deep copy of corresponding section has to be created and each id changed in it so that Ember handles it as another entity.

In Ember you can add Copyable  mixin to your object and then implement method copy(). That’s fine, but what if you want to make it generic for anything? Other approach we all know is deep copy by serialization/deserialization.

If you are using Ember Data it is likely that you have your own serializer and adapter. So in order to implement deep copy you will need a bit of “magic”. Here it is:

copySection: function(source, target, sectionName){
    var sourceSection = source.get(sectionName);
    var copiedSection = sourceSection.serialize();
    var type = source.constructor.metaForProperty(sectionName).type;
    var serializer = this.store.serializerFor(type.typeKey);

    // traverse your copiedSection and generate new ID for each child

    var normalized = serializer.extractSingle(this.store, type, copiedSection, copiedSection.id, 'findById');
    var deserialized = this.store.push(type, normalized);
    target.set(sectionName, deserialized);
},

Hope it comes handy for someone.


No comments


Ember data 1.0.0-beta4 “Adding unsaved records to hasMany relationships after they are normal” broke my code by duplicating child items after save operation on parent

January 2, 2014 EmberJS No comments

There was commit to Ember data and delivered with ember-data 1.0.0.-beta4 that broke my code.
Just in case you face similar issue, sharing this with you.
In that commit guy fixes issue with oneToMany relationship, when child items if they were not saved (i.e. are still in ‘isNew’ state) won’t be in list of child items after parent got saved. Apparently this happens because server doesn’t return unsaved child items.
Please see my comment and corresponding commit:
https://github.com/emberjs/data/commit/829753e4cb66d6ac93bac5b9983ed7056633d266#commitcomment-4969509

This is completely fine for traditional REST backend that handles each item separately, but what we implemented at work is backend that handles parent item with all child items. So request/response is complete graph. In our case all child items are automatically saved with parent object. Since server returns child item it will be in list of child items. Instead code that guy committed will add child item once again, since object in memory is still with ‘isNew’ state.
This is my fix, that I’ve added to our DS.ApplicationStore


Basically it  recursively marks all child items as committed before base didSaveRecord is called and attempts to add them if state is ‘isNew’.
You can notice that changing state is bit crazy – calling adapterWillCommit and adapterDidCommit, but it was only one way I found to do this. Unfortunately state manager is no longer part of ember.
Hope this helps someone.
[Update 2015/07/08: Looks like this got fixed as of ember-data 1.0.0.-beta4]


No comments


Integrating jQuery Chosen plugin with EmberJS and Bootstrap

December 7, 2013 EmberJS, JavaScript, Web No comments

I would like to show you how Chosen can be quickly integrated into your EmberJs application together with Twitter Bootstrap.

If you just want a solution, here is my gist: https://gist.github.com/andriybuday/7849057

Otherwise read a short story with some comments and “excuses” from my side.

I’m currently working on web application. We use JavaScript MVC web framework called EmberJs. It is very cool framework, and I will write about it more in the future. Ember has small set of views and input-helpers. Just using them is not always enough to build solid and rich application. Fortunately there are tons of controls available online, and it is quite easy to write your own controls with Ember.

Most of online available controls/plugins are based on jQuery (no surprises, of course) and they use plain javascript objects. Ember wraps javascript objects into Ember.Object, so it allows for data binding, data tracking and other advanced features, but on other hand it makes impossible to use vast majority of web components right away. You need to adapt them in order to to use them with Ember.

Having component created with Ember would result in application-specific html-tag, that would use JavaScript logic defined by you. Something like: <my-own-html-tag… that does and shows what you want.

Chosen. One of the controls we wanted to use was Chosen. “Chosen is a jQuery plugin that makes long, unwieldy select boxes much more user-friendly.” It allows you to have nice multi-selects that look like one below:

image

I’ve found a quick way to integrate chosen with Ember. As per me easiest way would be to utilize existing view called Ember.Select. You can embed it into your new component.

To be completely fair, my solution is not perfect, since I needed to hack html generated by Ember and manually handle selection/deselection of elements from the list, but solution below allowed me to achieve results fast without much code.
(Other option would be to avoid using Ember.Select and then play a lot with defining proper view for your component.)

If you are one of my constant readers, it might be bit surprising that I’m writing about web, and not even from .NET perspective. But believe me, you can expect more. I wanted to do more programming in other languages. This is why I struggled to try many programming languages. But thanks to some coincidences I currently code in javascript most of my time.


No comments