Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

ng-options include array properties #11733

Closed
wulfsberg opened this issue Apr 26, 2015 · 14 comments
Closed

ng-options include array properties #11733

wulfsberg opened this issue Apr 26, 2015 · 14 comments

Comments

@wulfsberg
Copy link

If an array contains additional properties (notably, as when fetched with Restangular, which adds several functions to the array), these extra properties are included in the iteration for ng-options, leading to unexpected "junk" entries in the select dropdown.

This differs from the iteration when using ng-repeat over the same array, which does not include such properties.

(This is new behavior in v1.4 rc0 and rc1. v1.3 does not show this behavior)

@Narretz
Copy link
Contributor

Narretz commented Apr 27, 2015

You mean props starting with $ and $$?

@Narretz Narretz added this to the Purgatory milestone Apr 27, 2015
@wulfsberg
Copy link
Author

Functions as well, yielding some very bizarre <options> when inspecting the HTML.

@superasn
Copy link

If it is of any help:

Please take a look at this fiddle:

http://jsfiddle.net/fggx31k7/

Open the extended Array drop-down (SELECT), you will see all sorts of things like functions, length, etc.

Preview

This was not happening until Angular 1.3.

https://jsfiddle.net/superasn/k2uwdjh5/ (working fine)

@Narretz Narretz self-assigned this Apr 29, 2015
@Narretz
Copy link
Contributor

Narretz commented Apr 29, 2015

Thanks, this is helpful. (although both your fiddles have 1.4.0-rc.1. You can also use plnkr.co, where it's simpler to switch dependencies)

@superasn
Copy link

Sorry about that.. I've updated the second fiddle, please try it here:

https://jsfiddle.net/superasn/k2uwdjh5/1/

@petebacondarwin
Copy link
Member

This is a bug. Let's fix it.
To be clear, though, there are a few different scenarios here:

  • A real array containing a function as one of its items
  • An extended array object containing a function as an instance property
  • An extended array object with a function on its prototype
  • An extended array object containing a non-function as an instance property
  • An extended array object with a non-function on its prototype
  • An array-like object containing a function as an instance property
  • An array-like object with a function on its prototype
  • An array-like object containing a property as an instance property
  • An array-like object with a property on its prototype
  • A non-array-like object containing a function as an instance property
  • A non-array-like object with a custom function on its prototype

What do you think should happen in each of these cases?

@wulfsberg
Copy link
Author

My somewhat fast and cheap answer would be "the same as ng-repeat". It makes sense that those two treat iterating over objects the same way.

@caitp
Copy link
Contributor

caitp commented Apr 30, 2015

ng-repeat doesn't deal with non-arraylike objects anymore

@caitp
Copy link
Contributor

caitp commented Apr 30, 2015

wait I'm wrong, it totally still does. how did we not get rid of that yet

petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Apr 30, 2015
…s `ngRepeat`

In `ngRepeat` if the object to be iterated over is "array-like" then it only iterates
over the numerical indexes rather than every key on the object. This prevents "helper"
methods from being included in the rendered collection.

This commit changes `ngOptions` to iterate in the same way.

BREAKING CHANGE:

Although it is unlikely that anyone is using it in this way, this change does change the
behaviour of `ngOptions` in the following case:

* you are iterating over an array-like object, using the array form of the `ngOptions` syntax
(`item.label for item in items`) and that object contains non-numeric property keys.

In this case these properties with non-numeric keys will be ignored.

** Here array-like is defined by the result of a call to this internal function:
https://github.com/angular/angular.js/blob/v1.4.0-rc.1/src/Angular.js#L198-L211 **

To get the desired behaviour you need to iterate using the object form of the `ngOptions` syntax
(`value.label` for (key, value) in items)`).

Closes angular#11733
@petebacondarwin
Copy link
Member

Here is a fix (#11771) that makes ngOptions follow the same logic as ngRepeat. @wulfsberg & @superasn can you see if this fixes your problems?

There is a tiny breaking change. @Narretz & @caitp what do you think - is that too big a BC to get it into 1.4.0?

petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Apr 30, 2015
…s `ngRepeat`

In `ngRepeat` if the object to be iterated over is "array-like" then it only iterates
over the numerical indexes rather than every key on the object. This prevents "helper"
methods from being included in the rendered collection.

This commit changes `ngOptions` to iterate in the same way.

BREAKING CHANGE:

Although it is unlikely that anyone is using it in this way, this change does change the
behaviour of `ngOptions` in the following case:

* you are iterating over an array-like object, using the array form of the `ngOptions` syntax
(`item.label for item in items`) and that object contains non-numeric property keys.

In this case these properties with non-numeric keys will be ignored.

** Here array-like is defined by the result of a call to this internal function:
https://github.com/angular/angular.js/blob/v1.4.0-rc.1/src/Angular.js#L198-L211 **

To get the desired behaviour you need to iterate using the object form of the `ngOptions` syntax
(`value.label` for (key, value) in items)`).

Closes angular#11733
@Narretz
Copy link
Contributor

Narretz commented Apr 30, 2015

Breaking Change is okay, as there's a pretty simple workaround. And it doesn't affect many people.

@superasn
Copy link

superasn commented May 1, 2015

My somewhat fast and cheap answer would be "the same as ng-repeat".

Yes, that would be great. For example, filterFilter also doesn't work with Array like objects anymore, like it used to before.

Please take a look at this fiddle:

Works like it should with previous version of Angular (v1.2):
https://jsfiddle.net/superasn/gznzjgmb/

Breaks with newer versions of Angular (v1.3 and above):
https://jsfiddle.net/superasn/c15yvq6g/

@petebacondarwin
Copy link
Member

@gkalpak is there any reason why we can't support array-like collection with filterFilter?
@superasn could you create a separate issue for that so that we can track it when this issue gets closed?

@superasn
Copy link

superasn commented May 1, 2015

@petebacondarwin i have created a new issue here:

#11782

netman92 pushed a commit to netman92/angular.js that referenced this issue Aug 8, 2015
…s `ngRepeat`

In `ngRepeat` if the object to be iterated over is "array-like" then it only iterates
over the numerical indexes rather than every key on the object. This prevents "helper"
methods from being included in the rendered collection.

This commit changes `ngOptions` to iterate in the same way.

BREAKING CHANGE:

Although it is unlikely that anyone is using it in this way, this change does change the
behaviour of `ngOptions` in the following case:

* you are iterating over an array-like object, using the array form of the `ngOptions` syntax
(`item.label for item in items`) and that object contains non-numeric property keys.

In this case these properties with non-numeric keys will be ignored.

** Here array-like is defined by the result of a call to this internal function:
https://github.com/angular/angular.js/blob/v1.4.0-rc.1/src/Angular.js#L198-L211 **

To get the desired behaviour you need to iterate using the object form of the `ngOptions` syntax
(`value.label` for (key, value) in items)`).

Closes angular#11733
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.