Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Cannot observe changes to nested properties on array using @each #541

robharper opened this Issue · 37 comments

23 participants

Rob Harper Peter Wagenet Yehuda Katz Tom Dale Christopher Swasey Kris Selden Tony Pitale Piotr Sarnacki Michael Jakub Arnold Patrick Hammer Peter HWest Jo Liss Tim Evans meelash Dan de Havilland Krutius kingpin2k Sergey S Microfed Panagiotis Panagi dowsanjack
Rob Harper

Adding an observer on a nested property of objects within a collection does not reliably fire. I've created a test case that could be added to ember-runtime/tests/mixins/array_test.js that illustrates this. Observing a nested property on the EachProxy itself appears to work fine. However, observing the property using @each.nest.isDone does not.

In the following test, count1 is incremented to 1, count2 is not:

test('modifying nested contents of an object in an array should call @each observers', function() {
  var ary = new TestArray([
      Em.Object.create({ nest: Em.Object.create({ isDone: false}) }),
      Em.Object.create({ nest: Em.Object.create({ isDone: false}) }),
      Em.Object.create({ nest: Em.Object.create({ isDone: false}) }),
      Em.Object.create({ nest: Em.Object.create({ isDone: false}) })

  var get = Ember.get, set = Ember.set;
  var count1 = 0, count2 = 0;

  // Works
  var each = get(ary, '@each');
  Ember.addObserver(each, 'nest.isDone', function() { count1++; });

  // Doesn't work
  Ember.addObserver(ary, '@each.nest.isDone', function() { count2++; });

  count1 = count2 = 0;
  var item = ary.objectAt(2);
  get(item, 'nest').set('isDone', true);

  equal(count1, 1, '@each.nest.isDone should have notified - observing @each array');
  equal(count2, 1, '@each.nest.isDone should have notified - observing chain containing @each');
Peter Wagenet

@each is only supported one level deep. It would be nice to allow more, but I don't know how difficult this would be technically. I'll let @wycats or @tomdale chime in on this.

Yehuda Katz

I don't think that's actually true... It uses the normal chain infrastructure and should work arbitrarily many levels deep.

Peter Wagenet

@wycats This sounds like a bug then. I've never seen it work more than one level deep.

Tom Dale

Agreed, this sounds like a bug. I believe this was working at some point. Thank you for the unit test.

Christopher Swasey

So I've been puzzling through this. It seems to boil down to EachProxy handling setting up the observers internally when you call addObserver with itself as the root. When as part of a chained path, however, the ChainNode plucks the top-level keyname off of the EachProxy, and goes on its merry way, and the EachProxy never gets involved. Basically, there are two levels of arrays at play.

watching '@each.nest.@each.isDone' DOES work, in this instance.

Christopher Swasey

Forgot to clarify that when the ChainNode plucks the keyname off the EachProxy, it's getting an EachArray, hence the need for nesting the @ each observers.

Kris Selden

The way chains work is each chain node has a corresponding chainWatcher that watches the key on the node's parent's value(), in order for this to work the chain needs to stop at @each and setup the chainWatcher with the remaining path.

I'm considering special casing @ character to just mean this.

Peter Wagenet

@kselden, does your simplify-properties branch touch on this at all?

Peter Wagenet

Looks like this is still an issue.

Kris Selden

chains do not chain through properties that produce arrays, this requires some changes I stated above, no I haven't done any work on it. It also is problematic @each itself changes when the array does.

Tony Pitale

I've hacked around this, for anyone that is facing this issue (especially when using ember-data associations), by adding a property on one side of the association that checks the property in the other end of the association (in my case, isLoaded) and then using that after the @each. As I said, this is a hack. But until 1.1, it works for me.

Piotr Sarnacki

@tpitale: could you show an example of such hack? I'm not sure what you mean by adding a property on other side of association.

@kselden @wagenet: I encountered something similar recently, but frankly I'm not sure if this is the same bug, could you take a look at this fiddle: ?

Tony Pitale

@drogus given the original example, there would be a nestIsDone property for the path nest.isDone. So you could observe @each.nestIsDone.


would really love to see this in 1.0 not 1.1 :+1:

Peter Wagenet

@mspisars Me too, but I don't want to block 1.0 on things that are difficult to fix and non-essential.

Jakub Arnold

last activity 4 months ago ... :+1:

Peter Wagenet

@mspisars, @darthdeus I would love to see it in 1.0 too. The issue is not about desire, it's about ability.

Patrick Hammer

:+1: for 1.0: would be really useful to have this working.


:+1: for 1.0

Peter Wagenet

Public Service Announcement: +1s do not provide development resources where they are lacking.

We've already agreed that we'd love to have this feature but it's very much non-trivial to support. It's certainly not something we'll block 1.0 on.

Christopher Swasey

Agreed with @wagenet these are non-trivial code paths that touch mission critical parts of ember.


Any updates on this? We have been trying to use this for a web app that's about to be used by a major Hotel chain and none of the workarounds seem to work. The only workable solution at this point is to redesign this part of the interface to make it simpler which is a shame.
Any information would be greatly appreciated and thanks for all your great work.

Jo Liss

It's a surprisingly hard problem. Part of the issue is that even if you implemented it or worked around it, updating a dependent array (which seems to be be the most common use case) would take O(n*2) time, which is a big problem even for fairly small datasets. To get it to be O(n), we'd need smarter array primitives to compose dependent arrays. There has been *some work on this by Peter and others, and people are definitely interested in pushing it forward, but I wouldn't hold my breath.

Related: #1288, #2711.

For now I'd recommend generating the dependent arrays on the server, basically as "computed relationships".

Tim Evans

Here's another fiddle demonstrating this issue:


Example workaround, demonstrating nested @each:

Dan de Havilland

If this is on the backburner, it would be helpful to note this behaviour in the API docs (maybe I missed it?) as it took me a while to find this ticket.


@dandehavilland Exactly! It should definitly be noted here: ''. "" is still not working, i've needed days to find this out.


But technically you can view nested properties, just not nested collections of properties, right?

works - flagpole and flag are singular


but should be


** doesn't work - flags is a collection**

Jo Liss

@kingpin2k No, I don't believe any of those work. They won't update correctly.

[Edit: maybe I'm wrong]

Peter Wagenet

@kselden is this something you're likely to work on any time soon?

Peter Wagenet

This is documented as not working. It would be great to add, but it's obviously difficult / not high enough a priority. If someone wants to work on it, we'd be happy to review a PR.

Peter Wagenet wagenet closed this
Sergey S

You can just add new computed property, which will contains only very nested object, which you're trying to observe. And @each will works correctly
Use next method

  allTickets: function () {
    var sections = this.get('sections'),
      each = Ember.$.each,
      tickets = [];

    each(sections, function (i, section) {
      each(section.rows, function (j, row) {
        each(, function (k, ticket) {

    return tickets;

  checkedCount: function () {
    ///custom logic
    return something;

instead of

  checkedCount: function () {
    ///custom logic
    return something
Panagiotis Panagi

This is so easy to miss in the guides. I believe it should issue a warning when a nested @each is found.


Yea, I agree. It should at-least throw a warning :+1:

m-obrien m-obrien referenced this issue from a commit in emberjs/website
Jo Liss joliss Document that nested @each does not work acb945c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.