1

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"?

2 Answers 2

2

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>
Sign up to request clarification or add additional context in comments.

4 Comments

For performance reasons, I would not recommend using the function there. This function will be called each time when change detection runs.
It is not a function, It will just return array of keys
Object.keys() is not a function? Sure, it will return an Array of keys, but the function that creates this array of keys will be called each time CD runs.
The pipe solution seems great.
1

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.