A Simple Guide to Navigation in Ionic 2



·

If you come from an Ionic 1 or Angular 1 background, then you would be used to handling navigation through routing with URLs, states and so on. It is actually still possible to use the old style of navigation in Ionic 2, but it’s not something I’ve paid much attention to so if you’re interested I’d recommend you take a look at this article.

The focus in Ionic 2 though is using a navigation stack, which involves pushing views onto the navigation stack and popping them off. Before we get into the specifics of how to implement this style of navigation in Ionic 2, let’s try to get a conceptual understanding of how it works first.

Pushing and Popping

Imagine your root page is a piece of paper that has a picture of a cat on it, and you put that piece of paper on a table. It is the only piece of paper currently on the table and you are looking down on it from above. Since it is the only piece of paper on the table right now, of course you can see the picture of the cat:

Drawn on my laptops trackpad, no judging

Drawn on my laptops trackpad, no judging

Now let’s say you want to look at a different piece of paper (i.e. go to a different page), to do that you can push it onto the stack of papers you have. Let’s say this one is a picture of a dog, you take that piece of paper and place it over the top of the picture of the cat:

navdog

The cat is still there, but we can’t see it anymore because it is behind the dog. Let’s take it even further and say that now you want to push another piece of paper, a cow, it would now look like this:

This one looks more like a Bellsprout than a cow

This one looks more like a Bellsprout than a cow

Both the cat and the dog are still there, but the cow is on top so that is what we see. Now let’s reverse things a bit. Since all of the pieces of paper are stacked in the order they were added we can easily cycle back through them by popping. If you want to go back to the picture of the dog you can pop the stack of papers, removing the piece of paper that is currently on top (the cow). If you want to go back to the picture of the cat you can pop the stack of papers once more to remove the piece of paper that is now on top (the dog). Now we’re back to where we started.

I’m sure you can see how this style of navigation is convenient for maintaining history and it makes a lot of sense when navigating to child views, but it doesn’t always make sense to push or pop. Sometimes you will want to go to another page without the ability to go directly back to the page that triggered the change (a login screen that leads to the main app for example, or even just different sections of an app available through a menu).

In this case, we could change the root page which, given our pieces of paper on the table analogy, is like disregarding the other stack of papers we have and just focusing on a new piece of paper on the table:

navcow2

In the example above, I’ve set the cow page as the root page, so rather than being on top of the other pages, it’s all by itself.

When should you push and when should you set the root page?

At first, it may be hard to understand whether you should set the root page to navigate to a different page or push the view. In general, if the view you want to switch to is a child of the current view, or if you want the ability to navigate back to the previous view from the new view, you should push. For example, if I was viewing a list of artists and tapped on one I would want to push the details page for that artist. If I was going through a multi-page form and clicked ‘Next’ to go to page 2 of the form, I would want to push that second page.

If the view you are switching to is not a child of the current view, or it is a different section of the application, then you should instead change the root page. For example, if you have a login screen that leads to the main application you should change the root page to be your main logged in view once the user has successfully authenticated. If you have a side menu with the options Dashboard, Shop, About and Contact you should set the root page to whichever of these the user selects.

Keep in mind that the root page is different to the root component, typically the root component (which is defined in app.component.ts) will declare what the root page is – the root page can be changed throughout the application, the root component can not.

Basic Navigation in Ionic 2

Ok, so now we’re going to get into a more practical Ionic 2 example and look at how to push, pop, set the root page and even how to pass data between pages. It’s all pretty simple really.

An important part of all this is the NavController. You will often see this imported by default in your Ionic 2 applications:

import { NavController } from 'ionic-angular';

and it also needs to be injected into the constructor:

@Component({
  templateUrl: 'home.html',
})
export class MyPage {
  constructor(public navCtrl: NavController) {

  }
}

A reference to the NavController is created so that we can use it anywhere within the class. So let’s take a look at how to push and pop.

To push a page, that means to make it the current page, you can do something like this:

    this.navCtrl.push(SecondPage);

This uses the reference to the NavController we created before, and all you need to supply to it is a reference to the component that you want to navigate to, which you will need to make sure you also import at the top of the file:

import { SecondPage } from '../second-page/second-page';

and that’s it, your app should switch to the new page whenever the push code is triggered. When you push a page, a ‘Back’ button will automatically be added to the nav bar, so you often don’t need to worry about using pop to navigate back to the previous page since the ‘Back’ button does this automatically for you.

There may be circumstances where you do want to manually pop a page off of the navigation stack though, in which case you can use this:

this.navCtrl.pop();

Easy enough right? As I mentioned before there is still another way to change the page and that is by setting the root page. If you take a look at your app.ts file you will notice the following line:

    rootPage: any = MyPage;

Declaring a member variable rootPage in the root component will set the root page. To change the root page at any point throughout the application, you can use our mate the NavController – all you have to do is call the setRoot function like this:

this.navCtrl.setRoot(SecondPage);

Passing Data Between Pages in Ionic 2

A common requirement of mobile applications is to be able to pass data between pages. In Ionic 2 this can be done using NavParams. First, you must pass through the data you want within the push call (this can also be done when using setRoot):

    this.navCtrl.push(SecondPage, {
        thing1: data1,
        thing2: data2
    });

This is exactly the same as what we were doing before, except now there is an extra parameter which is an object that contains the data we want to send through to SecondPage. Then on the receiving page we need to import NavParams and inject it into our constructor:

import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';

@Component({
    templateUrl: 'second-page.html'
})
export class SecondPage {

    constructor(public navCtrl: NavController, public navParams: NavParams){

    }
}

Then you can grab the data that was passed through by doing the following:

this.navParams.get('thing1');

Summary

It might be a little difficult to get your head around at first, especially if you’re not familiar with the pushing and popping concept, but once you get used to it I think this is a very simple and powerful form of navigation.

What to watch next...

  • Richard Shergold

    These are great tutorials Josh. Thanks.

  • Jason Malfatto

    Thanks for another elegant lesson, Josh.

  • Michaël Doukan

    Ho Josh, Just a question. Ionic 2 can work with the branch 1.x of angular ?
    Thanks,
    mdouke

  • Lars Jeppesen

    I f*cking love you, this is great stuff! Ng2 + Ionic2 is a killer!

  • Pingback: Build a Todo App from Scratch with Ionic 2 [VIDEO TUTORIAL] | HTML5 Mobile Tutorials | Ionic, Phaser, Sencha Touch & PhoneGap()

  • stewones

    Very Nice dude. Thx for saving my time haha

  • Mateus Santana

    Nice!
    I have a one question. I’m using the push to redirect the user to another page of my app. The point is that when I use the push it automatically inserts the back button, just not accurate dess back button, how do I disable?

  • kkap

    I implemented navigation in my ionic2 app. from my root page, I provide a link to navigate to another page using this.nav.push(SecondPage, {}). The navigation works perfect in chrome/web browser. But it doesn’t work in android emulator 🙁 .anybody has nay clue what might be going wrong in emulator?

  • ZiLang

    My question is how to pass data back when I call this.nav.pop()? Is it even possible? Thanks.

    • You might want to look into using a Modal, you can attach an onDismiss listener to a Modal which will allow you to send data back to the page that launched the Modal.

  • SP1966

    I have a ClientListPage as the rootPage, when I navigate to the AddClientPage and add a client I am then taken to a ClientDetailsPage. I want to remove the AddClientPage from the navigation stack such that the back button in the navbar will take the user back to the ClientListPage. When I use the remove() method I end up having to hit the back button a couple times before it navigates. setRoot doesn’t work either.

    Any ideas?

  • usman rehman

    Hi josh. need little help.
    can you please tell how can we use popTo for a particular page. like i want to go several pages back. according to ionic we can use popTo but its not working.
    http://ionicframework.com/docs/v2/api/components/nav/NavController/#popTo

    Looking for your reply!
    thanks

  • Dominik Bleilevens

    Thanks Josh for this tutorial!
    Short question: Is it possible to use a Slide Left Animation when popping pages? I made some research, but wasn’t able to find a solution.

  • Pingback: Using Angular 2 without Ionic 2: Part 1 | HTML5 Mobile Tutorials | Ionic, Phaser, Sencha Touch & PhoneGap()

  • Alejandro Planter

    Where can i import the “this.nav.push(SecondPage);” ???

    Tacos

  • Alejandro Planter

    It just don’t work on Beta 7

    • The code in this tutorial should work with beta.7, what are you having an issue with?

      • Alejandro Planter

        Well, i made a click button, and when i clicked it doesn’t do nothing

      • Alejandro Planter

        or this tutorial it’s written on TypeScript?

  • Pingback: Build a Todo App from Scratch with Ionic 2 [VIDEO TUTORIAL] | HTML5 Mobile Tutorials | Ionic, Phaser, Sencha Touch & PhoneGap()

  • Ben O’Connor

    Hey Josh, how do we handle the click handler? I followed along and this matches my notes, but I’m not getting the new page to push.
    I’m using

    • Chin Sem Chang

      In the class of your first page (HomePage), write a function called “SecondPage” which does “this.nav.push(SecondPage);”

      • Ben O’Connor

        Got that, but to trigger that function, you need a click handler in the html.
        What are you guys writing there? That’s where I’m breaking things.

      • Make sure that you 1) Have a click handler in the template, ie 2) Have a corresponding function in the class that calls this.nav.push(SecondPage) 3) Have NavController imported in the class and that this.nav references that 4) Import the “SecondPage” component at the top of the class

      • Cool! Thanks Josh – got it. I had typos in the NavController import line 🙂 Helpful having that step-by-step so I could narrow it down. Love your work.

      • Chin Sem Chang

        You got the click handler right. You may wanna put a console log to see if the function is triggered when you click on the button. Chances are it is not triggered.

      • Thanks for your help – appreciate it 🙂

  • Cameron Glackin

    Great tutorial, really like the image explanation. I don’t often comment on tutorials, but this one made a lot of sense to me and I didn’t need to read it twice.
    Thanks!

  • shine

    Great explanations regarding pages with the cat/dog/cow. Simple and effective. Thanks so much!

  • Stacktx

    Thanks, this help me alot
    btw.: how no one realized that cow isnt a bellsproud at all but it is a weepbell 😀 (Bellsproud evolution)

  • hllink

    so, if im at page 5 and want to go back programatically to page 3, how we do it?

  • Kingsley Simon

    Hi Josh, when i use the push to another page, it goes to that page but then it refreshes and shows a blank screen. Do you know why this happens?

  • Markus Reich

    hi josh, great tutorial thank you ver much! As I think you are the expert concernig navigation, I have a question to you 🙂 is it possible to override the standard back button? I want to call my own function when clicking on back?

  • Mayra A. Rodriguez M

    Can I do this.navCtrl.pop() and send params to the previous view?

  • andrew

    very useful article. thanks for sharing this awesome piece. godbless

  • Will Ivancic

    From the View Creation documentation: By default, pages are cached and left in the DOM if they are navigated away
    from but still in the navigation stack (the exiting page on a push() for
    example). They are destroyed when removed from the navigation stack (on
    pop() or setRoot(). Thus, if I use setRoot() to navigate to a new sections, I loose any active activities in a previous sections (root). Is there a way to have multiple active pages and easily move between them with a mix of Tabs and non-tab pages. Would one use something like “setPages”? For me, the documentation on setPages is difficult to understand. Pages are supposedly and array. How does one determine the array or pages and what are the options that could be passed? Perhaps in the future you could provide and example.

    Basically, is there a way to make a particular viewController active, that is specify which viewController you want active?

  • Jamie

    How can you pass a variable to the page function? What is the correct syntax? That way you could have just a general function you could use to push or pop a page.

    Example:

    HTML:
    Directory Listing (Push)

    .TS:
    pushpage(event) {
    this.navCtrl.push(event);
    }

  • Khoa Đặng

    Thanks for the tutorial. Detailed, useful and easy to understand.

  • DimaNYC

    Something about that Cow drawing…

  • Sandumini Lochana

    Thank You so much this sloved my problem with in 1 minute

  • Alex Lu

    Thanks Josh! This is helpful. I was wondering if how should I remove tabs on the subpages, e.g. information editing pages, etc. ?

  • Sylvain Huon

    Ho man you saved my App ! For some reason, I did not noticed the setRoot solution before !
    Cheers

  • Thanks you so much ! 😀

  • சந்துரு

    :-{D