fairlie
fairlie

Reputation: 87

Angular 2 Dynamic menu from json

I am trying to create bootstrap navbar menus dynamically using Angular 2. The source data for the menu comes from json which looks like below:

[
  {
    name: 'Dashboard',
    url: '/dashboard',
    writeble: true,
    icon: 'icon-speedometer'
  },
  {
    name: 'Menu1',
    url: '/menu1',
    writeble: true,
    icon: 'icon-puzzle',
    children: [
      {
        name: 'Item1.1',
        url: '/item/item1.1',
        writeble: true,
        icon: 'icon-puzzle'
      },
      {
        name: 'Item1.2',
        url: '/item/item1.2',
        writeble: true,
        icon: 'icon-puzzle'
      }
    ]
  }
]

Currently, my menu is hardcoded in this way into the navbar.component.html, I have to create a function into component.ts where read the json file and then how to store the data and send it to html?

<div id="context-menu"class="custom-menu">
   <li ngbDropdown class="nav-item dropdown pointer" 
     <a class="nav-link dropdown-toggle" ngbDropdownToggle 
       href="javascript:void(0);" id="menu1">                           
       <span>Menu1</span>
    </a>
    <ul class="dropdown-menu" ngbDropdownMenu>
        <li>
        <a class="dropdown-item" [routerLink]="['Item1.1']" 
           [routerLinkActiveOptions]="{ exact: true }"                             
           (click)="collapseNavbar()">
           <span>Item1.1</span>
        </a>
        </li>
        <li>
            <a class="dropdown-item" [routerLink]="['Item1.2']" 
            routerLinkActiveOptions]="{ exact: true }"
            (click)="collapseNavbar()">
            <span>Item1.2</span>
            </a>
        </li>                    
        </ul>
    </li>
</div>

Can you suggest how I can replace the hardcoded menu items with the dynamic one? Thanks.

Upvotes: 1

Views: 9523

Answers (2)

Iancovici
Iancovici

Reputation: 5731

This is a two part questions, so here's the answer to each concept individually.

Important JSON to data structure array

  1. Create a data structure relevant. (see below for example)

    export class DataTypeName { name: string; desc: string; type: string;

    }

  2. Create a function that uses observable or promise to fetch data, and make it in same format as json file.

    import { Http, Response } from '@angular/http';

    import {Observable} from 'rxjs';

    import 'rxjs/add/operator/map';

(in your component or service.ts)

  //private URL ='./<insert file path here> '
  //private URL = 'https://<or insert url path here>'
  getDataFile(): Observable<DataTypeName []> {
    return this.http.get(this.URL)
      .map((response: Response) => response.json());

Implement Dynamic Drop Down

Then iterate through data using*ngFor for li tags

<ul class="dropdown-menu" ngbDropdownMenu>
 <li *ngFor="let item of list"> 
  <a [routerLink]="[item.url]" > 
     <span>{{item.name}}</span>
  </a>
 </li>
</ul>

Upvotes: 1

nirazlatu
nirazlatu

Reputation: 993

You can at first store the json data in an array i.e. menus and then, do something like this:

 <div id="context-menu"class="custom-menu">

   <ng-container *ngFor="let menu of menus">

   <ng-container *ngIf="menu.children && menu.children.length > 0">
      <li ngbDropdown class="nav-item dropdown pointer" 
      <a class="nav-link dropdown-toggle" ngbDropdownToggle 
         href="javascript:void(0);" id="{{menu.id}}">                           
      <span>{{menu.name}}</span>
     </a>

    <ul class="dropdown-menu" ngbDropdownMenu>
      <li *ngFor="let child of menu.children">
    <a class="dropdown-item" [routerLink]="['child.url']" 
       [routerLinkActiveOptions]="{ exact: true }"                             
       (click)="collapseNavbar()">
       <span>{{child.name}}</span>
     </a>
     </li>
     </ul>

     </li>

   </ng-container>


  <ng-container *ngIf="!menu.children || (menu.children && menu.children.length === 0">
    <li ngbDropdown class="nav-item dropdown pointer" 
      <a class="nav-link dropdown-toggle" ngbDropdownToggle 
         href="javascript:void(0);" id="{{menu.name+'_id'}}">                           
      <span>{{menu.name}}</span>
     </a>
     </li>

  </ng-container>
  </ng-container>
  </div>

Storing in Array:

  Export from JSON file and Importing in Component

      //jsonfile.ts
      export const menuJSON= [
        { 'name': '---', 'url':----, 'children': [{'name': '--', 'url': 
           '--'}]},
        { 'name': '---', 'url':----, 'children': [{'name': '--', 'url': 
        '--'}]},
        { 'name': '---', 'url':----, 'children': null},
        ];

       //yourcomponent.ts

       import { menuJson } from './jsonfile';
       let menus: Array<any> = menuJson;

       //use menus now

Upvotes: 1

Related Questions