I use an array to store a list of group objects and an array of a list of light objects. I want to show the first group in the html and all connected lights to that group. After that the next group and the related lights and so on....
<div>
<ul>
<li *ngFor="let group of hueGroups">
{{group.name}}
<li *ngFor="let light of hueLights; let i = index">
{{hueLights[group.lights[i]].name}}
</li>
</ul>
</div>
export class AppComponent implements OnInit {
hueGroups:any[];
hueLights:any[];
constructor(){
this.hueGroups = [];
this.hueLights = [];
}
listAllGroups(){
for(var g in MyHue.Groups){ //MyHue.Groups returen an array with objects
console.log(g);
console.log(MyHue.Groups[g].name);
for(var id:number = 0; id < MyHue.Groups[g].lights.length; id++){
console.log("LightID:" + MyHue.Lights[MyHue.Groups[g].lights[id]].name); // Returns the name of the Lights
}
this.hueGroups.push(MyHue.Groups[g]);
}
listAllLights(){
for(var l in MyHue.Lights){ //MyHue.Lights returns an array with objects
console.log(MyHue.Lights[l]);
this.hueLights.push(MyHue.Lights[l]);
}
}
}
If I try to run this I get the error
Cannot read property 'lights' of undefined
So I think the syntax is wrong for the nested ngFor. It should be possible to call "group" from above.
EDIT: This is the important part of how an object of the MyHue.Groups looks like:
{action:Object
class:"Living room"
lights: Array(2)
0:"3"
1:"1"
name:"Room1"}
In the Group object there is only the ID of the lights which are depending to this group
This is the important part of how a light object looks like:
{state: Object, type: "Extended color light", name: "Couch1", modelid: "LCT007"…}
This is what I get if I print the hole array to the console:
Object {1: Object, 3: Object, 4: Object}
So I have to match which Light ID is in which Group, then check the light Object for the name
Looks like you need to create a simpler data structure where your light objects are contained in an array property of your hueGroup objects. Then you'll be able to iterate easily through your groups, and each of their lights in your template.
For example, your template should look more like this:
<ul>
<li *ngFor="let group of hueGroups">
{{group.name}}
<ul>
<li *ngFor="let light of group.lights">
{{light.name}}
</li>
</ul>
</li>
</ul>
And your component should contain a hueGroups
data object or model to render.
hueGroups = [{
name: "group 1",
lights: [{
name: "light 1"
},{
name: "light 2"
}]
},
{
name: "group 2",
lights: [{
name: "light 3"
},{
name: "light 4"
}]
}];
Check out this plunker for a working example of what I mean: http://plnkr.co/edit/THXdN8zyy4aQMoo4aeto?p=preview
The key here is using your template to reflect the content of the component's data that's backing it. Beyond my example, you might want to use typescript to define an interface or class for your groups and lights.
Your example is a little more complicated because your template is trying to render a synthesis of two data structures (your hueGroup.lights seem to be arrays of just light ids). I'd recommend making a function that creates a hueGroup object with embedded light objects your template can iterate over easily. Here's an example of such a function:
Updated to reflect the example data:
ngOnInit(){
this.hueGroups = this.hueGroupSource.map((group)=>{
let lightObjects = group.lights.map((lightID)=>{
return this.hueLightsSource.find((light, index) => {return index === lightID});
});
group.lights = lightObjects;
return group;
});
}
Here is a plunker showing it in a working example. http://plnkr.co/edit/V309ULE8f6rCCCx1ICys?p=preview
I managed to get this working with the below nested ngFors
:
<ion-card *ngFor="let exercise of exercises">
<ion-card-header>
<ion-card-title>
{{exercise.name}}
</ion-card-title>
</ion-card-header>
<ion-item *ngFor="let set of exercise.sets">
set: {{set.setNo}}
reps: {{set.reps}}
weight:{{set.weight}}
</ion-item>
</ion-card>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With