In general, I find components in Ionic 2 to be simpler and easier to understand than their V1 versions, but for some reason, I was incredibly confused by the docs for working with the Menus component. Documentation exists of course, but it just didn't make sense to me. (I documented my problems in this issue for folks curious.) What follows is my own understanding of how to work with menus in Ionic 2 and some basic things to keep in mind. As always, remember I'm still learning this myself, so keep in mind I may get a detail or two wrong.

Before we continue, a few links:

  • First, the main component doc.
  • Then the related API doc.
  • Finally, the Sidemenu starter app. I did not use this when learning, and it does a few things differently. I'll talk about that at the end.

Alright, so to begin, I created a new Ionic 2 app with the blank template:

ionic start sidemenudemo blank --v2

This gave me a blank slate to begin by demo. In my demo, I want a site with three pages:

  • A home page
  • A cats page
  • A dogs page

Out of the box you get a home page, so I used the CLI to generate the two other pages:

ionic g page cats ionic g page dogs

If you weren't aware, the CLI has a generate feature which can write boilerplate code for you. I highly recommend using it.

Alright, so the first thing you have to do when working with a side menu is create a new page. (See my note at the bottom!) So given my app has three pages, I needed a fourth page to host the menu. I created a new one called main.

If you want my demo, you can find it here: https://github.com/cfjedimaster/Cordova-Examples/tree/master/sidemenudemo

ionic g page main

Since my app starts with the side menu, I decided to make main my root page for the app. So my first modification was to app.component.ts:


import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';

import { MainPage } from '../pages/main/main';

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage = MainPage;

  constructor(platform: Platform) {
    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      StatusBar.styleDefault();
      Splashscreen.hide();
    });
  }
}

Essentially I just changed "Home" to "Main" in the import and the line where rootPage is set. So far so good. Now let's set up the main page to have my menu. Here is main.html:


<ion-menu [content]="mycontent">

	<ion-content>
		<ion-list>
			 <button ion-item menuClose (click)="openPage(homePage)">
				Home
			</button>
			<button ion-item menuClose (click)="openPage(catsPage)">
				Cats
			</button>
			<button ion-item menuClose (click)="openPage(dogsPage)">
				Dogs
			</button>
		</ion-list>
	</ion-content>

</ion-menu>

<ion-nav #mycontent [root]="rootPage"></ion-nav>

There are a couple of very important things here to note. First let's start on line one:


<ion-menu [content]="mycontent">

The [content]="mycontent" aspect confused the heck out of me. All it really means though is this: "When I load crap, I want you to load it in this container." You'll notice at the bottom I've got an ion-nav component that uses the #mycontent identifier there.

Now look at the menu code. Most of it is self-explanatory but I want to call out two things.

First, menuClose tells the menu to automatically close when a menu item is clicked. This is not the default, so most likely you will always want to add this.

Second, what's openPage(x) about? This is shown in the docs but not explained. Basically, you have to write the code to load new pages. This is easy of course, but the docs don't spell this out for you. Going from Ionic 1, I didn't have to do this because I simply used URLs I had already set routes up for.

Here is my main.ts:


import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { HomePage } from '../home/home';
import { CatsPage } from '../cats/cats';
import { DogsPage } from '../dogs/dogs';


@Component({
  selector: 'page-main',
  templateUrl: 'main.html'
})
export class MainPage {

  private rootPage;
  private homePage;
  private catsPage;
  private dogsPage;

  constructor(public navCtrl: NavController, public navParams: NavParams) {
    this.rootPage = HomePage;

    this.homePage = HomePage;
    this.catsPage = CatsPage;
    this.dogsPage = DogsPage;

  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad MainPage');
  }

  openPage(p) {
    this.rootPage = p;
  }

}

As you can see, openPage is pretty simple.

So that's it - but let me address one thing in particular when you compare my code to the SideMenu starter. For the application I was working on (an existing Ionic 1 app migrating to Ionic 2), the menu loads after an initial login screen. Therefore, using 4 pages (one for each page plus one for the menu) made sense. If you look at the SideMenu template though, they modify the main app.html file that is the root of the Ionic app itself. It is the first page, and the core I guess you could call it, so that made sense. If that's how your app starts up, I'd do that instead of creating another page as I've done here.