1

Sorry for not giving an example to use but I'm not sure how to create codepen angular 5 examples. Anyways. I want to know if it is possible to use *ngFor to repeat through this array, but only show values once (no duplicates). Check my example image of buttons for how it should look. Is this possible with THIS array? Maybe using pipes or something like that?

enter image description here enter image description here

4

1 Answer 1

1

A possible solution:

First structure your array:

this.array = [
    {level1: "1", level2: "1.1", level3: "1.1.1"},
    {level1: "1", level2: "1.1", level3: "1.1.2"},
    {level1: "1", level2: "1.2", level3: "1.2.1"}
];

this.fa = {}
this.array.forEach(obj => {
    if(!this.fa[obj.level1]) this.fa[obj.level1] = {};
    if(!this.fa[obj.level1][obj.level2]) this.fa[obj.level1][obj.level2] = [];
    this.fa[obj.level1][obj.level2].push(obj.level3)
})

It assumes you have only 3 levels. Then you will get the following structure:

{
    "1": {
        "1.1": [
            "1.1.1",
            "1.1.2"
        ]
    }
}

Then iterate through in template:

<div *ngFor="let i of Object.keys(fa)">
    {{i}}
    <div *ngFor="let j of Object.keys(fa[i])">
        {{j}}    
        <div *ngFor="let k of fa[i][j]">
            {{k}}
        </div>
    </div>
</div>

Don't forget to bind the Object variable to your template adding the following line in your component:

Object = Object;

Complete example:

@Component({
    selector: 'app',
    template: `
        <div *ngFor="let i of Object.keys(fa)">
            {{i}}
            <div *ngFor="let j of Object.keys(fa[i])">
                {{j}}
                <div *ngFor="let k of fa[i][j]">
                    {{k}}
                </div>
            </div>
        </div>
    `,
})
export class AppComponent {

    array = [
        {level1: "1", level2: "1.1", level3: "1.1.1"},
        {level1: "1", level2: "1.1", level3: "1.1.2"},
        {level1: "1", level2: "1.2", level3: "1.2.1"}
    ];

    fa = {};

    Object = Object;

    constructor() {
        this.array.forEach(obj => {
            if (!this.fa[obj.level1]) this.fa[obj.level1] = {};
            if (!this.fa[obj.level1][obj.level2]) this.fa[obj.level1][obj.level2] = [];
            this.fa[obj.level1][obj.level2].push(obj.level3)
        })
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for the answer. It seems much shorter than the other answers, but I can't seem to get it working. I think there is something wrong in the html template? I don't understand the Object.keys thing
My bad, you must add Object=Object in the composenent to makes it accessible in the template.
Say again? Sorry I don't understand 100%. Should I add "Object = Object;" in the component? Would you update your example please? I prefer your answer but I can't get it to work
To make a javascript global variable (as Object) accessible to your template, you must bind it. So in your component you must add the following line Object = Object inside the Typescript code of your component like this: @Component({...}) export class ... { ... Object = Object; ... }. I will add a complete compilable example.
yes it works man! I can't exactly remember how I finally used it though. But I will mark yours. Thank you very much

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.