Matelutex
Matelutex

Reputation: 2210

Angular 8 + PrimeNG PanelMenu - how to dynamically add menu items

Is it possible to set menu items based on data fetched from database?

import {Component, OnInit} from '@angular/core'; import {MenuItem} from 'primeng/api';

@Component({
  selector: 'app-questionnaire',
  templateUrl: './questionnaire.component.html',
  styleUrls: ['./questionnaire.component.scss'],
})
export class QuestionnaireComponent implements OnInit {
  items: MenuItem[];

  constructor() {
  }

  ngOnInit() {
    this.items = [
      {
        label: 'Environmental',
        items: [
          {
            label: 'Question 1',
            icon: 'pi pi-circle-on',
          },
          {
            label: 'Question 2',
            icon: 'pi pi-circle-on',
          },
          {
            label: 'Question 3',
            icon: 'pi pi-circle-on',
          },
        ],
      }, {
        label: 'Social',
        items: [
          {
            label: 'Question 4',
            icon: 'pi pi-circle-on',
          },
          {
            label: 'Question 5',
            icon: 'pi pi-circle-on',
          },
          {
            label: 'Question 6',
            icon: 'pi pi-circle-on',
          },
        ],
      },
      {
        label: 'Governance',
        items: [
          {
            label: 'Question 7',
            icon: 'pi pi-circle-on',
          },
          {
            label: 'Question 8',
            icon: 'pi pi-circle-on',
          },
          {
            label: 'Question 9',
            icon: 'pi pi-circle-on',
          }, {
            label: 'Question 10',
            icon: 'pi pi-circle-on',
          },
        ],
      },
    ];
  }
}

and my template:

<div class="questionnaire questionnaire-container">
  <div class="intro"></div>
  <div class="content">
    <div class="progress-bar">
      PROGRESS BAR
    </div>
    <div class="side-menu">
      <p-panelMenu [model]="items" [style]="{'width':'300px'}"></p-panelMenu>
    </div>
    <div class="questionnaire-content">
      QUESTIONNAIRE CONTENT
    </div>
  </div>
</div>

I'm asking you because I don't know if its possible to do that in component, not in template where I could use *ngFor= and then generate menu items... If it's not possible, then I would find some other library for menu...

Upvotes: 1

Views: 4753

Answers (1)

Elmehdi
Elmehdi

Reputation: 1430

Yes it is possible.
You will just have to use Angular's http client to request the data you want, then subscribe to it and assign the resuts to this.items.
The trickiest part is gonna be formatting you data from your API to a format that can be understood by PrimeNG menu panel. In the example below I make a call to an API that returns to me a formatted items which I can assign directly to this.items :

  ngOnInit() {
    this.http
      .get("https://express-demo-feat-test2-s8pihd.herokuapp.com/api/items")
      .subscribe(data => (this.items = data as MenuItem[]));
  }

Here is a link to a stackblitz demo
If you need to format your data before using it you can do something like this:

  ngOnInit() {
    this.http
      .get("https://express-demo-feat-test2-s8pihd.herokuapp.com/api/items")
      .pipe(
         map(data => {
           // do some formatting
         })
      )
      .subscribe(data => (this.items = data as MenuItem[]));
  }

Upvotes: 2

Related Questions