3

I have an array like following:

causes: any= [
{
    'Specification': {
        'Missing':false,
        'Unclear':false,
        'Wrong':false,
        'Changed':false,
        'Better Way':false,
    },
    'Design': {
        'Missing':false,
        'Unclear':false,
        'Wrong':false,
        'Changed':false,
        'Better Way':false,
    },
    'Code': {
        'Missing':false,
        'Unclear':false,
        'Wrong':false,
        'Changed':false,
        'Better Way':false,
    },
    'Documentation': {
        'Missing':false,
        'Unclear':false,
        'Wrong':false,
        'Changed':false,
        'Better Way':false,
    },
}]

How can I iterate over it in my template? I tried something like:

<div class="mdl-grid">
    <div *ngFor=" let chunk of causes | chunks: 2; let j = index; " class="mdl-cell mdl-cell--4-col">
        <label *ngFor=" let cause of chunk| values " #checkbox class="mdl-checkbox mdl-js-checkbox">
            <input type="checkbox" name="causes" class="mdl-checkbox__input">
            <span class="mdl-checkbox__label">{{cause}}</span>
        </label>
    </div>
</div>

But it still gave me [object Object]. I am trying to populate each cause and against it those 5 checkboxes.

2
  • 1
    ngFor only accepts an array, but you're trying to iterate over an object from what I can see. Commented Apr 6, 2017 at 12:33
  • let chunk of causes[0] should clarify the situation a bit. Commented Apr 6, 2017 at 12:57

2 Answers 2

5

In the code that you presented you only have one object inside array.

I assume that your array should look like this:

causes: any = [
    {
        name: 'Specification',
        values: {
            'Missing': false,
            'Unclear': false,
            'Wrong': false,
            'Changed': false,
            'Better Way': false,
        },
    },
    {
        name: 'Design',
        values: {
            'Missing': false,
            'Unclear': false,
            'Wrong': false,
            'Changed': false,
            'Better Way': false,
        },
    },
    {
        name: 'Code',
        values: {
            'Missing': false,
            'Unclear': false,
            'Wrong': false,
            'Changed': false,
            'Better Way': false,
        },
    },
    {
        name: 'Documentation',
        values: {
            'Missing': false,
            'Unclear': false,
            'Wrong': false,
            'Changed': false,
            'Better Way': false,
        },
    }
]

Your html should look like this

    <div class="mdl-grid">
        <div *ngFor=" let chunk of causes" class="mdl-cell mdl-cell--4-col">
            <div>Checkboxes for {{chunk.name}}</div>
            <div *ngFor=" let cause of chunk.values | keys">
               <label  #checkbox class="mdl-checkbox mdl-js-checkbox">
                   <input type="checkbox" [name]=" chunk.name + '_' + cause" class="mdl-checkbox__input">
                    <span class="mdl-checkbox__label">{{cause}}</span>
               </label>
            </div>
        </div>
    </div>

Where keys pipe is a custom pipe that returns keys of the object, which is array of strings. Code for pipe:

Pipe

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'keys',
    pure: false
})
export class KeysPipe implements PipeTransform {
    transform(value, args: string[]): any {
        return Object.keys(value);
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

This is a better solution, it's just that it is only printing []false,[]true with this code and not like: Specification with five checkboxes each with label Missing, Unclear etc.
Yes perfect! I did it already :) Thanks for the suggestion to change the array structure. It makes more sense!
Cheers! Glad it helped.
If i understood you correctly, i created a plunker example: plnkr.co/edit/rOuKEDHLOCfBOBjwB2Xi
Yes correc, exactly thatt! Thanks!
2

Iterating over an object is not possible out-of-the box. However, you can use custom pipe like the below.

  import { PipeTransform, Pipe } from '@angular/core';
  @Pipe({name: 'keys'})
  export class KeysPipe implements PipeTransform {
    transform(value, args:string[]) : any {
     let keys = [];
     for (let key in value) {
       keys.push(key);
      }
      return keys;
    } 
  }

And use it as

  <tr *ngFor="#c of content">           
   <td *ngFor="#key of c | keys">{{key}}: {{c[key]}}</td>
  </tr>

Have a look here

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.