-
Notifications
You must be signed in to change notification settings - Fork 27.4k
fix(ngRepeat): do not sort object keys alphabetically #10538
Conversation
BREAKING CHANGE: Previously, the order of object properties was consistent and simple. Now, it's not guaranteed to be any particular order at all. The best approach is to convert Objects into Arrays by a filter such as https://github.com/petebacondarwin/angular-toArrayFilter or some other mechanism, and then sort them manually in the order you need. Closes angular#6210
+1 angular.toArray(object); <li ng-repeat="item in itemHash | toArray">
{{ item }}
</li> |
Thanks @caitp! We need to refactor those tests so that they don't rely on any particular ordering. Perhaps so that we iterate over the object in the tests as well so that the ordering differences per browser are cancelled out? We also need to update the |
Also we need to think about sorting an object whose properties are not objects. For instance, if you had the following object: var obj = {
a: 'A',
b: 'B',
c: 'C'
}; Then you can use the expect(toArrayFilter(obj, false)).toEqual(['A', 'B', 'C']); If you try to attach the We can't solve this inside the |
The JavaScript spec does provide any warranties on the iteraration I think we should not merge this |
The approach taken is actually entirely safe, despite not being spec'd --- It gets complicated if you mix elements with properties, but for strictly properties set at creation time, there is no engine which will get this wrong. Needless to say, the documentation could use an update, but someone else can worry about that Edit: Actually, enumeration is pretty normatively defined at this point --- surprisingly not in Annex B, but the behaviour of the enumeration order is essentially what browsers implement now (rather, the enumeration order isn't strictly defined, but enumeration order generally matches |
Some more grist for the mill: |
I know all about this stuff. The tests are safe, so if you want to fix out, push the button |
@caitp - I believe that what you are saying is that since we are simply assigning object properties we will not fall foul of browsers failing to order the properties as we expect. We still need to update the docs for ngRepeat to explain what people are letting themselves in for when iterating over an object's properties. It is a bit of a cop out to say this is someone else's problem. Moreover, we need to be clear in both the docs and tests exactly what the situation is with current browsers; why we can use the tests that we have but can't rely on order in general. In other words, that just about all browsers maintain the order in which the properties are added but that some browsers, such as IE, may not respect assignment ordering if you are re-assigning a property that was previously deleted, yes? Any other cases? This is important to prevent people from complaining in the future if things don't work out as expected. We should not merge this PR until these items are in place. |
I think the docs update can be done seperately |
@caitp - we cannot land a PR with a breaking change to the way a directive works without including a suitable update to the documentation. If you do not want to do this then I will update the appropriate sections at some point after New Year as part of merging this - unless someone else wants to offer a docs update PR to merge in with this change. Also what do you think of splitting |
If someone shows me a use case which is widely needed, then I'm all for it |
@petebacondarwin I find your suggestion to split ng-repeat in ng-repeat for arrays and ng-object for objects an excellent one. I also agree with @caitp ''but honestly it's not really helping you do anything, and it's a really weird thing to depend on.'' regarding the remove of the sort. |
I added documentation and landed. Thanks to everyone who has had input in this issue. |
BREAKING CHANGE: Previously, the order of items when using ngRepeat to iterate over object properties was guaranteed to be consistent by sorting the keys into alphabetic order. Now, the order of the items is browser dependent based on the order returned from iterating over the object using the `for key in obj` syntax. It seems that browsers generally follow the strategy of providing keys in the order in which they were defined, although there are exceptions when keys are deleted and reinstated. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete#Cross-browser_issues The best approach is to convert Objects into Arrays by a filter such as https://github.com/petebacondarwin/angular-toArrayFilter or some other mechanism, and then sort them manually in the order you need. Closes #6210 Closes #10538
BREAKING CHANGE:
Previously, the order of object properties was consistent and simple. Now, it's not guaranteed to
be any particular order at all.
The best approach is to convert Objects into Arrays by a filter such as https://github.com/petebacondarwin/angular-toArrayFilter
or some other mechanism, and then sort them manually in the order you need.
Closes #6210