Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

ng-repeat with a Map not working #359

Closed
saeimn opened this issue Dec 17, 2013 · 17 comments
Closed

ng-repeat with a Map not working #359

saeimn opened this issue Dec 17, 2013 · 17 comments
Assignees

Comments

@saeimn
Copy link
Contributor

saeimn commented Dec 17, 2013

When trying to use ng-repeat over a map:

<span ng-repeat="(key, value) in {'a': 1, 'b': 2, 'c': 3}">
{{key}}: {{value}}
</span>

which is described in the Angular JS documentation:
http://docs.angularjs.org/api/ng.directive:ngRepeat#!

I get the following error:
type '_LinkedHashMap' is not a subtype of type 'List' of 'value'.

@ghost ghost assigned IgorMinar Dec 17, 2013
@mhevery
Copy link
Contributor

mhevery commented Dec 18, 2013

This is intentional. We found that there were many issue with iterating over Maps, and so we decided not to support this feature.

@mhevery mhevery closed this as completed Dec 18, 2013
@saeimn
Copy link
Contributor Author

saeimn commented Dec 19, 2013

Could we at least have a better error message then? This is very misleading because it diverges from Angular JS.

@zoechi
Copy link
Contributor

zoechi commented Jan 7, 2014

Is there some workaround?

I tried:

<div ng-repeat="key in ctrl.map.keys.toList()">{{key}}</div>
seems not to work either

[Eval Error: Undefined function ctrl.mapKeys.toList while evaling [ctrl.mapKeys.toList()]]

I added a method on the controller that returns the keys of the map. Using this method worked
<div ng-repeat="key1 in ctrl.mapKeys(ctrl.map)">key1: {{key1}}

Then I tried to repeat over a nested map which failed at
<div style="margin-left:60px;" ng-repeat="key3 in ctrl.mapKeys(ctrl.map[key1][key2]))">key2: {{key2}}

Again adding a method to the controller solved this
<div style="margin-left:60px;" ng-repeat="key3 in ctrl.mapKeys(ctrl.mapValue(ctrl.map, key1, key2))">key2: {{key2}}

Obviously such an expression ctrl.map[key1][key2] (two concatenated list accessors) can't be evaluated inside {{}}

Should this work. Is this planned?
Is there a better way?

@mhevery
Copy link
Contributor

mhevery commented Jan 7, 2014

Can you write a custom filter to do this?

<div ng-repeat="keyValue in trl.mapKeys | myMapToList">key1: {{keyValue.key}} - {{keyValue.value}}

Something which consumes a map and spits out a list?

@mhevery
Copy link
Contributor

mhevery commented Jan 7, 2014

Filed #394

@zoechi
Copy link
Contributor

zoechi commented Jan 8, 2014

Thanks for you feedback!
I'm not yet used to filters but I will try this out.

@yx-will
Copy link

yx-will commented Mar 17, 2014

I almost cried after having spent my whole good Sunday on finding out why my ng-repeat didn't print anything until I stumbled upon this page. I converted Map to an array of Objects and it finally works.

@fringd
Copy link

fringd commented Mar 23, 2014

since the new change detection and some other work scheduled for 1.0 are going to fix ng-repeat over map.keys and map.values, doesn't it become possible to fix this bug and support (key, value) syntax in ng-repeat again? It would be great to have this just work for people migrating from angular.js, and it's just a handy syntax. Any chance of re-opening this issue?

@mhevery
Copy link
Contributor

mhevery commented Mar 24, 2014

iterating over keys is problematic since key order is not guaranteed. We
feel that we made a mistake in supporting it in AngularJS v1.x and would
like to reset this expectation in v2.0. So it is unlikely that we would
support this again.

On Sun, Mar 23, 2014 at 4:00 PM, fringd [email protected] wrote:

since the new change detection and some other work scheduled for 1.0 are
going to fix ng-repeat over map.keys and map.values, doesn't it become
possible to fix this bug and support (key, value) syntax in ng-repeat
again? It would be great to have this just work for people migrating from
angular.js, and it's just a handy syntax. Any chance of re-opening this
issue?


Reply to this email directly or view it on GitHubhttps://github.com//issues/359#issuecomment-38400875
.

@vicb
Copy link
Contributor

vicb commented Mar 24, 2014

Would it makes sense to allow iterating over keys for linked hash maps whose order is guaranteed ?

On 24 mars 2014 15:25:54 CET, "Miško Hevery" [email protected] wrote:

iterating over keys is problematic since key order is not guaranteed.
We
feel that we made a mistake in supporting it in AngularJS v1.x and
would
like to reset this expectation in v2.0. So it is unlikely that we would
support this again.

On Sun, Mar 23, 2014 at 4:00 PM, fringd [email protected]
wrote:

since the new change detection and some other work scheduled for 1.0
are
going to fix ng-repeat over map.keys and map.values, doesn't it
become
possible to fix this bug and support (key, value) syntax in ng-repeat
again? It would be great to have this just work for people migrating
from
angular.js, and it's just a handy syntax. Any chance of re-opening
this
issue?


Reply to this email directly or view it on
GitHubhttps://github.com//issues/359#issuecomment-38400875
.


Reply to this email directly or view it on GitHub:
#359 (comment)

@mhevery
Copy link
Contributor

mhevery commented Mar 25, 2014

order is guaranteed, but it is rather random. When you do ng-repeat you
most likely want ordered list or some other custom ordering. For this
reason this feature request should be solved through filters. Also why
special case one particular implementation of Map. If we allow iteration
over Map then it should be over all types of Maps not just LinkedHashmap.

On Mon, Mar 24, 2014 at 8:43 AM, Victor Berchet [email protected]:

Would it makes sense to allow iterating over keys for linked hash maps
whose order is guaranteed ?

On 24 mars 2014 15:25:54 CET, "Miško Hevery" [email protected]
wrote:

iterating over keys is problematic since key order is not guaranteed.
We
feel that we made a mistake in supporting it in AngularJS v1.x and
would
like to reset this expectation in v2.0. So it is unlikely that we would
support this again.

On Sun, Mar 23, 2014 at 4:00 PM, fringd [email protected]
wrote:

since the new change detection and some other work scheduled for 1.0
are
going to fix ng-repeat over map.keys and map.values, doesn't it
become
possible to fix this bug and support (key, value) syntax in ng-repeat
again? It would be great to have this just work for people migrating
from
angular.js, and it's just a handy syntax. Any chance of re-opening
this
issue?


Reply to this email directly or view it on
GitHub<
https://github.com/angular/angular.dart/issues/359#issuecomment-38400875>
.


Reply to this email directly or view it on GitHub:
#359 (comment)


Reply to this email directly or view it on GitHubhttps://github.com//issues/359#issuecomment-38460088
.

@fringd
Copy link

fringd commented Mar 25, 2014

I think linked hash map promises the same order you put in right? many
other map implementations will guarantee order as well. Perhaps just warn
people that using maps with unstable order is likely to make the user
experience terrible.

More to the point, now that i think if it... we have all these problems
already iterating over map.keys

Filters sound like a good solution too... What would it look?

for item in aMap.keys | stabilizeOrder

or something else?
On Mar 24, 2014 8:10 PM, "Miško Hevery" [email protected] wrote:

order is guaranteed, but it is rather random. When you do ng-repeat you
most likely want ordered list or some other custom ordering. For this
reason this feature request should be solved through filters. Also why
special case one particular implementation of Map. If we allow iteration
over Map then it should be over all types of Maps not just LinkedHashmap.

On Mon, Mar 24, 2014 at 8:43 AM, Victor Berchet [email protected]:

Would it makes sense to allow iterating over keys for linked hash maps
whose order is guaranteed ?

On 24 mars 2014 15:25:54 CET, "Miško Hevery" [email protected]
wrote:

iterating over keys is problematic since key order is not guaranteed.
We
feel that we made a mistake in supporting it in AngularJS v1.x and
would
like to reset this expectation in v2.0. So it is unlikely that we would
support this again.

On Sun, Mar 23, 2014 at 4:00 PM, fringd [email protected]
wrote:

since the new change detection and some other work scheduled for 1.0
are
going to fix ng-repeat over map.keys and map.values, doesn't it
become
possible to fix this bug and support (key, value) syntax in ng-repeat
again? It would be great to have this just work for people migrating
from
angular.js, and it's just a handy syntax. Any chance of re-opening
this
issue?


Reply to this email directly or view it on
GitHub<
https://github.com/angular/angular.dart/issues/359#issuecomment-38400875>

.


Reply to this email directly or view it on GitHub:

#359 (comment)


Reply to this email directly or view it on GitHub<
https://github.com/angular/angular.dart/issues/359#issuecomment-38460088>
.


Reply to this email directly or view it on GitHubhttps://github.com//issues/359#issuecomment-38517386
.

@mturilin
Copy link

Guys, this is really confusing. I just spent 2 hours trying to figure out why this doesn't work:
Dart:

class Controller {
    var some_map  = {
        'aaa': 111, 'bbb': 222, 'ccc': 333
      };
     var some_map_keys;

     Controller() { 
         some_map_keys = some_map.keys;
      }
}

HTML:

    <p>Map: {{ctrl.some_map }}</p>
    <p>Map.keys: {{ctrl.some_map.keys }}</p>
    <p>Map.keys.toList(): {{ctrl.some_map.keys.toList() }}</p>
    <p>List copy: {{ctrl.some_map_keys }}</p>

Result:

 Map: {aaa: 111, bbb: 222, ccc: 333}
 Map.keys:
 Map.keys.toList():
 List copy: (aaa, bbb, ccc)

I can speak only for myself. For me the selective behavior for Maps is counter-intuivive. I think if the template engine supports iteration over ANY Iterable then Map.keys should be supported.

Thoughts?

@vicb
Copy link
Contributor

vicb commented Jul 24, 2014

This issue has already been discussed ans should be fixed when #1040 is in.
With the current implementation, accessing Map.keys will return Map[keys] (root cause being the context is a map, see other issues for details). After #1040, Map.keys and Map[keys] will return either the property or the item as you expect.

@mturilin
Copy link

Got it! Thanks for the great explanation!

@nerdrew
Copy link
Contributor

nerdrew commented Nov 8, 2014

Did this ever get fixed? It doesn't seem to work with LinkedHashMap in 1.0.0.

@ronyongxian
Copy link

does it support iterate map in ng-repeat now? for my opinion, just iterate with original order is ok. just like ng-options.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

10 participants