-
Notifications
You must be signed in to change notification settings - Fork 27.4k
AngularJS is throwing "Error: key.charAt is not a function" on Firefox when $filter is iterating over some kind of strange Object #15644
Comments
If we can't rely on Object keys being strings, where is this world headed? I assume that somehow iterating over the keys of a |
I think that must be it. I'm not familiar with iterators' behavior, but my goog.structs.Map did have numeric keys in the this.keys_ array, and I guess each one of those was being returned by the iterator. |
How about we change |
Or someone needs to poke johnlenz |
key[0] would work for me personally, but would not work for keys that are null or undefined. |
True! I am a little on the fence with this one. I don't want to introduce extra work for every filtering operation, just to support some dubious, ultra-edgy usecase, where keys are not strings 😕 @seriesoftubes, if you want to put together a PR (using |
I agree-- key[0] should be perfectly fine in the vast majority of cases. I have no idea why they chose I wish I had more time to file a proper PR-- I opened this issue hoping that there would be an easier way for someone else to fix it. |
No worries! Soemone will take care of it. So, if anyone is up for a little PR, without a way to test this (so no tests to be added), adding a -if ((key.charAt(0) !== '$') && deepCompare(actual[key], expected, comparator, anyPropertyKey, true)) {
+if (key.charAt && (key.charAt(0) !== '$') && deepCompare(actual[key], expected, comparator, anyPropertyKey, true)) { Writing the commit message (and explaining how an Objects |
Previously, when an object has keys which are not of type string, `filterFilter` would throw an exception for trying to call `key.charAt()`, which is a string method. This commit checks whether `charAt` is defined before calling it. Fixes angular#15644 Closes angular#15660
Summary
When $filter is used against an array of custom objects, I received this console error in 1.5:
Error: key.charAt is not a function
deepCompare@https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.js:20587:16
deepCompare@https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.js:20587:42
deepCompare@https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.js:20587:42
createPredicateFn/predicateFn@https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.js:20562:12
filterFilter/<@https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.js:20526:12
And in 1.6:
Error: key.charAt is not a function
deepCompare@https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js:20564:16
deepCompare@https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js:20564:42
deepCompare@https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js:20564:42
createPredicateFn/predicateFn@https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js:20539:12
filterFilter/<@https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js:20503:12
anonymous/fn@https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js line 15156 > Function:2:489
regularInterceptedExpression@https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js:16264:55
Steps to repro:
I saw this bug when iterating over a goog.structs.Map, and noticed that
key
was actually a number. Sorry, I can't reproduce this without figuring out how to pull in closure on plnkr. And it is still hard for me to believe that afor (var key in obj)
loop can produce non-string keys, so I don't know how else to possibly reproduce it.The best I can say is that this definitely was an issue on >= Angular 1.5 on Firefox (but not Chrome). I'm not sure about IE.
Possible fix:
checking for
typeof key === 'string'
here: https://github.com/angular/angular.js/blob/master/src/ng/filter/filter.js#L229
The text was updated successfully, but these errors were encountered: