John Theoden
John Theoden

Reputation: 325

Accessing json object array and showing in Angular 4

I have object that consists of fields, other objects and arrays and it looks like this

Now, in my html, I access data for aaType, adjust etc.

<div class="flexdirectioncolumn">
    <div class="flex50">
        <label class="label-prop-a"> Name </label>
        <div>
            <input #name type="text" value={{entity.name}} (keyup.enter)="changeName(name.value)" />
        </div>
    </div>
    <div class="flex50">
        <label> AaType </label>
        <div>
            <input #aaType type="text" value={{entity.aaType}} (keyup.enter)="changeAaType(aaType.value)" />
        </div>
    </div>
    <div class="flex50">
        <label> Adjust </label>
        <div>
            <input #adjustableInput type="checkbox" value={{entity?.adjust}} (keyup.enter)="changeAdjust(adjustInput.value)" />
        </div>
    </div>
    <div class="flex50">
        <label> System </label>
        <div>
            <input #systemInput type="text" value={{entity?.system}} />
        </div>
    </div>
    <div class="flex50">
        <label>{{entity.creat.rule}}</label>
        <div *ngFor="let param of entity.creat.parameters">
            <label>{{param}}</label>
            <input type="text" value={{param.value}} />
        </div>
    </div>
</div>

I managed to show creationInfo.rule that you can see in my html.

Now there is 2 questions that is bothering me:

  1. For some reason, I can't access parameters array so I can use ngFor to create them all.
  2. How can I show my label and input in ngFor div in a way that label will generate parameters name (like "departure-angle") and value in input to show "13"?

Upvotes: 1

Views: 1990

Answers (2)

Sravan
Sravan

Reputation: 18657

Question 1: For some reason, I can't access parameters array so I can use ngFor to create them all.

Answer 1: parameters is not an array it is an object, you cant iterate object using &ngFor

Question 2: How can I show my label and input in ngFor div in a way that label will generate parameters name (like "departure-angle") and value in input to show "13"?

Answer 2:

Solution 1: In Component add a new variable:

objectArray = Object.keys; // It gives the array of object keys

In html use *ngFor="let param of objectArray(entity.creationInfo.parameters)",

<div class="flex50">
    <label>{{entity.creationInfo.rule}}</label>
    <div *ngFor="let param of objectArray(entity.creationInfo.parameters)">
        <label>{{param}}</label>
        <input type="text" value={{entity.creationInfo.parameters[param]}} />
    </div>
</div>

Solution 2: You can add a pipe,

This pipe takes the object and return array of objects

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


@Pipe({name: 'array'})
export class ArrayPipe implements PipeTransform {
  transform(value, args:string[]) : any {
    let array = [];
    for (let key in value) {
      array.push({key: key, value: value[key]});
    }
    return array;
  }
}

In html,

<div class="flex50">
    <label>{{entity.creationInfo.rule}}</label>
    <div *ngFor="let param of entity.creationInfo.parameters | array">
        <label>{{param.key}}</label>
        <input type="text" value={{param.value}} />
    </div>
</div>

Upvotes: 2

pascalpuetz
pascalpuetz

Reputation: 5428

1.: Parameters is not an array but an Object. So you cannot use *ngFor to access them.

2.: Map the parameters to a key-value array before displaying them.

Inside your ts file:

public params:Array<{key: string, value: string}>;

// Call this method when the "entity" object has been initialized.
private setParams():void {
    this.params = Object.keys(this.entity.creationInfo.parameters)
         .map(paramKey => ({
             key: paramKey, 
             value: this.entity.creationInfo.parameters[paramKey]
         }));
}

And then, inside your template:

<div *ngFor="let param of params">
    <label>{{param.key}}</label>
    <input type="text" value={{param.value}} />
</div>

Another way to achieve this, is using the Object.entries() function:

public params:Array<Array<any>>;

// Call this method when the "entity" object has been initialized.
private setParams():void {
    this.params = Object.entries(this.entity.creationInfo.parameters);
}

Then, inside your template:

<div *ngFor="let param of params">
    <label>{{param[0}}</label>
    <input type="text" value={{param[1]}} />
</div>

Upvotes: 1

Related Questions