-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
computed.sort works incorrectly with empty sort properties array #13037
Comments
@onechiporenko Can you explain in more detail? It appears to me that the empty array used as |
Ember.Controller.extend({
list: [{a: 1}, {a: 2}, {a: 3}, {a: 4}, {a: 5}, {a: 6}, {a: 7}, {a: 8}, {a: 9}, {a: 10}, {a: 11}, {a: 12}, {a: 13}, {a: 14}, {a: 15}, {a: 16}, {a: 17}, {a: 18}, {a: 19}, {a: 20}],
sortBy: [],
sorted: Em.computed.sort('list', 'sortBy')
}); In this case [{a: 11}, {a: 1}, {a: 3}, {a: 4}, {a: 5}, {a: 6}, {a: 7}, {a: 8}, {a: 9}, {a: 10}, {a: 2}, {a: 12}, {a: 13}, {a: 14}, {a: 15}, {a: 16}, {a: 17}, {a: 18}, {a: 19}, {a: 20}]
Another example: Ember.Controller.extend({
list: [{a: 1}, {a: 2}, {a: 3}, {a: 4}, {a: 5}, {a: 6}, {a: 7}, {a: 8}, {a: 9}, {a: 10}],
sortBy: [],
sorted: Em.computed.sort('list', 'sortBy')
}); In this case [{a: 1}, {a: 2}, {a: 3}, {a: 4}, {a: 5}, {a: 6}, {a: 7}, {a: 8}, {a: 9}, {a: 10}] So, small collection wasn't changed but big one was changed. I've checked my example in few browsers and found out next: Windows 8: Ubuntu 15.10:
I have ember-addon (ember-models-table) that is a table with multi-columns sorting. And initially table is not sorted by any column. In this case I expect that data is shown in order that it is in the array. But its order is changed when Ember try to sort it by 'nothing' . |
@onechiporenko Thanks for reporting this. The current behaviour is definitely incorrect. If the sort properties are empty it should either throw an error or simply not sort the array. The latter option seems much better. |
A bit more details... The current implementation is effectively doing [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20].sort(() => 0); which surprisingly returns [11, 1, 3, 4, 5, 6, 7, 8, 9, 10, 2, 12, 13, 14, 15, 16, 17, 18, 19, 20] in Chrome (though not in Safari or Firefox) because Regardless, running |
I guess I don't really understand. Why would computed.sort be stable when Array#sort isn't? Why use computed.sort at all if you don't need to sort? |
@rwjblue, I'm working on addon called |
Lets see if I understand this correctly, @mmun et al, feel free to let me know if I missed a step given: const User = Ember.Object.extend({
bar: Ember.computed.sort('foo', 'propsToSort')
})
let foo = ['c','b','c'];
let user = User.create({ foo })
deepEquals(user.get('bar'), foo); // proposed
sometimesDeepEquals(user.get('bar'), foo); // current which depends on unstable sort We likely expect bar to mirror foo's ordering, until such time as |
The current behavior makes more sense to me (do whatever Array#sort does), and l I don't think this is specified behavior for computed.sort (it isn't documented to be a noop if no sort properties exist). However, if we decide that this was a breaking change for a scenario that we support I can get behind the PR, but I'd prefer if we deprecate/warn when calling sort without sort props to make it clearer that this is not a good use case for computed.sort. |
@rwjblue although not documented, I think it is least surprising for no-sort properties to equate to no change in the ordering from input. We may need to consider this a breaking change over a bugfix, at which point we may need a release plan. |
Not sure if it is least surprising. I would expect computed.sort to behave the same as Array#sort, but be aware of changes in the upstream array. Like I said, I'm fine with this being something we decide is supported behavior, it just seems odd to me. We either need to fully document that computed.sort is a noop with an empty sort props array, or deprecate this behavior. I am not a fan of the idea that every thing that has ever happened to work must be supported forever. If this is a thing we want to support, then let's document it. If this is a thing we must support because it is considered a breaking change (but we would prefer not to diverge from native Array#sort behavior) then we should fix and deprecate when sort props is an empty array. |
@rwjblue I strongly believe that sortProperties being falsy OR an empty array ought to be a no-op AND that it should be a documented behaviour. @onechiporenko's table example seems like a natural motivating use case to me. |
I can buy this, but today this also doesn't happen. sort without comparator, i belive coerces args to strings, then compares them let me illustrate
Before @mmuns patch:
After @mmuns patch:
And I am unsure what the behavior was in 1.13, but it may be different again. We should likely also take a look at 1.13.x behavior, just so we can get a full picture. The proposed change would extend the "no sort" clause to be basically |
Comparing Array#sort to computed.sort is a bit subtle. The API analog of
There is no analog to |
Like I said, I'm fine with this being something we decide to support. It should be covered with explicit tests and documented so I can't get confused in the future. 😸 |
@rwjblue totally. This is obviously a place where we underspecified and are now paying the price. |
any status change on this? |
@rwjblue @stefanpenner @mmun adding the label "Bug" for now, looks like the PR is in progress |
I confirm the inconstant behaviour, here is another example to showcase the issue https://ember-twiddle.com/4a1d8e3aa1bef71dd657431fd59cb445 it seems that array listeners are only set when sort properties array is not empty. |
Any news? |
I have a similar issue, I'm not sure if I need to open a new issue. I have a list that I sort twice. Once by date and then a second time in order to get the folder at the top of the list (I know I should use two lists ;) ). I noticed that the second sort is modifying the sort of the first one even if the sort function always returns The two following codes does not produce the same result, to me they should. The first snippet produces the correct results.
Should I open a new issue with a twiddle? |
Problem:
computed.sort
may do some "sorting" even if there aren't properties to sort.Demo: https://ember-twiddle.com/83ed55ef7169c8dacefe?openFiles=application.controller.js%2C (see second column)
Possible solution: Check if
normalizedSortProperties
is empty, don't do any sorting (https://github.com/emberjs/ember.js/blob/v2.4.1/packages/ember-runtime/lib/computed/reduce_computed_macros.js#L670)The text was updated successfully, but these errors were encountered: