ng2: iterate over object and display its keys...

109 views
Skip to first unread message

p. stephen w

unread,
Jul 30, 2016, 10:14:24 AM7/30/16
to AngularJS
ngFor only works on arrays and iterables - github-angular-issues

So what is the correct way to iterate over an object and display certain keys?

Example:
      woot = {bought:true, returned:'no', superBrandId:true, partnerBrand:false}

Output:
    <p>bought</p>
    <p>superBrandId</p>

Lucas Lacroix

unread,
Jul 30, 2016, 11:10:52 AM7/30/16
to AngularJS

Use a function that returns Object.keys to enumerate the keys. That's what I've done.


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at https://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Sander Elias

unread,
Jul 31, 2016, 2:57:25 AM7/31/16
to AngularJS
Hi P. Stephen,

On Object is not an iteratable, but a map is. you can easily conver to one like this:

woot = new Map(Object.entries({bought:true, returned:'no', superBrandId:true, partnerBrand:false}))

now woot is an iterable, you can easily traverse.

Regards
Sander

p. stephen w

unread,
Jul 31, 2016, 10:02:51 AM7/31/16
to ang...@googlegroups.com
Thanks for that.  I suspected something like that would be possible.



______________________________________
p. stephen wille
Where there's a Wille, there's a way.


--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/EtPS4FwcPWo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.

p. stephen w

unread,
Jul 31, 2016, 10:33:53 AM7/31/16
to AngularJS
Sounds like I need to create the array/Map before I can loop over it.  That presents a dilemma.  If I'm looping over an array of objects many levels deep,  how will I know which is the correct object for a given array index?  The only way I can see to allow NG2 to iterate over nested objects is, to transform the whole JSON blob, turning objects into arrays so they are compatible with *ngFor.

Am I missing something, or is there a better way?






On Sunday, July 31, 2016 at 7:02:51 AM UTC-7, p. stephen w wrote:
Thanks for that.  I suspected something like that would be possible.



______________________________________
p. stephen wille
Where there's a Wille, there's a way.


On Sat, Jul 30, 2016 at 11:57 PM, Sander Elias <sande...@gmail.com> wrote:
Hi P. Stephen,

On Object is not an iteratable, but a map is. you can easily conver to one like this:

woot = new Map(Object.entries({bought:true, returned:'no', superBrandId:true, partnerBrand:false}))

now woot is an iterable, you can easily traverse.

Regards
Sander

--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/EtPS4FwcPWo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+unsubscribe@googlegroups.com.

p. stephen w

unread,
Aug 1, 2016, 9:36:25 PM8/1/16
to AngularJS
Anyone?
Is the question unclear?

Lucas Lacroix

unread,
Aug 1, 2016, 9:50:30 PM8/1/16
to AngularJS

Could you put an example on plunkr? Even if it doesn't work, it will better explain what it is you are trying to do.


On Mon, Aug 1, 2016, 21:36 p. stephen w <p.steph...@gmail.com> wrote:
Anyone?
Is the question unclear?



On Sunday, July 31, 2016 at 7:33:53 AM UTC-7, p. stephen w wrote:
Sounds like I need to create the array/Map before I can loop over it.  That presents a dilemma.  If I'm looping over an array of objects many levels deep,  how will I know which is the correct object for a given array index?  The only way I can see to allow NG2 to iterate over nested objects is, to transform the whole JSON blob, turning objects into arrays so they are compatible with *ngFor.

Am I missing something, or is there a better way?





On Sunday, July 31, 2016 at 7:02:51 AM UTC-7, p. stephen w wrote:
Thanks for that.  I suspected something like that would be possible.



______________________________________
p. stephen wille
Where there's a Wille, there's a way.


On Sat, Jul 30, 2016 at 11:57 PM, Sander Elias <sande...@gmail.com> wrote:
Hi P. Stephen,

On Object is not an iteratable, but a map is. you can easily conver to one like this:

woot = new Map(Object.entries({bought:true, returned:'no', superBrandId:true, partnerBrand:false}))

now woot is an iterable, you can easily traverse.

Regards
Sander

--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/EtPS4FwcPWo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.

To post to this group, send email to ang...@googlegroups.com.
Visit this group at https://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.

Sander Elias

unread,
Aug 1, 2016, 11:30:51 PM8/1/16
to AngularJS
Hi,

Yes, the question is missing the details it needs to answer your question in a informed way. it's impossible to know without knowing the exact structure on your data.
It sounds like you got an big JS blob of denormalized data. That kind of data poses an challenge in its own. 
You can use functions like Object.keys in your template using a simple trick. 

Something like this will help:
import { Component } from 'angular2/core';

@Component({
  selector
: 'my-story',
 
template: `
    <div *ngFor="#a of keys(woot)" ><span *ngIf="woot[a]">{{a |json}}</span></div>
  `

})
export class StoryComponent {
  woot
=  {bought:true, returned:'no', superBrandId:true, partnerBrand:false};
  keys
= Object.keys;
}

The span is there because it's a bad idea to use two template directives on one element. However, this is putting some extra logic in your templates.
A alternate solution might be creating a special pipe tailored to your data.

Regards
Sander

p. stephen w

unread,
Aug 2, 2016, 9:31:49 PM8/2/16
to AngularJS
I was working on a Plunker, but couldn't get NG2/TS or ES6 working.  This bug report documents the ES6 problem.  Not sure about TS.
If you have a working NG2 Plunker template, that would speed things along.

https://github.com/filearts/plunker_www/issues/67



p. stephen w

unread,
Aug 2, 2016, 9:35:47 PM8/2/16
to AngularJS

Sander Elias

unread,
Aug 3, 2016, 1:01:31 AM8/3/16
to AngularJS
Hi P. Stephen,

I moved your plunker to the latest RC, and put in an extra component. I think it's enough to get you going. (PS you really should not put 2 components in 1 .ts file as I did in this sample! ;-) )
Made a small component that shows you how you can iterate recursively over a json.


Regards
Sander

p. stephen w

unread,
Aug 3, 2016, 9:49:44 PM8/3/16
to ang...@googlegroups.com
Very cool.  Thanks for taking the time to fix it. 
I see you import 'rxjs' to clear the 'map undefined' error.  That was really causing me some grief.

1. Was the systemjs.config auto populated?  It looks daunting to scribble out myself.
2. Extra points for using a recursive component. 
3. The travel.component does the trick, but it is a lot more work than NG1. 

One of the great things about NG1 was its ease of use, and looping through objects and arrays was a big part of that.  It allowed you to hydrate your templates with JSON, with minimal fuss.  I would vote for restoring that functionality.





______________________________________
p. stephen wille
Where there's a Wille, there's a way.


--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/EtPS4FwcPWo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.

Sander Elias

unread,
Aug 4, 2016, 1:33:42 AM8/4/16
to AngularJS
Hi,

It's a need to know that you have to import your operators. That's a bit of a PITA, until you find that ;)

1. Yes, I took the quick-start sample, from angualr.io and worked from that. While learning, don't spend too much time on figuring out stuff you need to build. angular-cli will take care of this for most applications. (the new version is/will be using webpack btw)
2. Noted ;)
3. yep.

The 'ease of use' of NG1 came also with a price to pay. A lot of 'magic' happened behind the curtain, If you didn't know what was happening behind that curtain, it became very easy to build a dog-slow app.
NG2 still allow you to hydrate your template with JSON very easily. 

<my-trav [showData]="data"></my-trav>

That's easy enough isn't it? ;) Just 1 single element to traverse (when needed) an JSON/Object/array/primitive

Well, after you created the needed component it is at least. The component itself is also relatively easy to build. And, (I can not stress this enough!) it put's you in full control of what happens. You decide on a very fain-grained level how and what gets displayed. This is something that was much harder to do in NG1!

Regards
Sander


p. stephen w

unread,
Aug 10, 2016, 9:53:50 PM8/10/16
to AngularJS
I hate to say it but I keep tripping over this issue. 
I like speedy apps, but the utility of "(key, val) in myObj" was spectacular, especially for Select elements.  Looking at NG2 forms Plunkr example, my first thought is, that's just too much work and too many files.   Instead of the templates consuming JSON, the data has to be transformed and modeled out in various classes to allow the templates to display it.  

Sander Elias

unread,
Aug 10, 2016, 11:57:19 PM8/10/16
to AngularJS
Hi 

That is a nice sample, but it goes to the fully fine-grained control edge. You can still 'generate' a form from a json doc, without much fuss. Have a look at this sample. Recursive iterating an json into a Formbuilder.group is not that hard. Traversing it into the template is also not that challenging. 
The docs are quite nice, but are a bit more focused on the more complex use-cases, and samples are made to show off all that is possible. That in itself is a good thing, but it might all look a bit more overwhelming as it actually needs to be.  

All the documentation you have read, makes it possible to create a template that does something like this:

<restform endpoint="api/client">
 
<validation field="name" required/>
 
<validation field="age" min="18"/>
</restform>

While building the the needed components to work up to that might be slightly more complex as it was in ng1, using it is much simpler. right? ;)

Regards
Sander
Reply all
Reply to author
Forward
0 new messages