Ionic Framework | How To Pass Data Between Pages

Written by on April 9, 2015

Ionic Framework | How To Pass Data Between Pages

Manual Data Sharing Between Controllers

Usually, we don’t want automatic updates between controllers. Some date needs to be accessed only during some situations. This case requires a little bit different approach than the last example.

Example

Demo

Embeded working example
Manual Data Sharing Between Controllers

HTML
<html ng-app="starter">
 
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width" />
  <title>Ionic Framework Example</title>
  <link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet"/>
  <script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
  <script src="script.js"></script>
</head>
 
<body>
  
  <!-- The nav bar that will be updated as we navigate -->
  <ion-nav-bar class="bar-positive">
    <ion-nav-back-button class="button-clear">
      <i class="ion-arrow-left-c"></i> Back
    </ion-nav-back-button>
  </ion-nav-bar>
  
  <ion-nav-view></ion-nav-view>
  
  <script id="list.html" type="text/ng-template">
    <ion-view view-title="First page">  
      <ion-content class="padding">
        <h2 style="text-align: center;">Manual Data Sharing Between Controllers</h2><br/>
        <h5 style="text-align: center;">Enter something into input box and go to the next page</h5><br/>
        <div class="list">
          <label class="item item-input item-stacked-label">
            <span class="input-label">First Name</span>
            <input type="text" placeholder="Enter your first name" ng-model="input.firstName">
          </label>
          <label class="item item-input item-stacked-label">
            <span class="input-label">Last Name</span>
            <input type="text" placeholder="Enter your last name" ng-model="input.lastName">
          </label>
        </div>        
        <a href="#/view" style="text-decoration: none;"><button class="button button-full button-positive">
          Open next page
        </button></a>      
      </ion-content>
    </ion-view>
  </script>  
  
  <script id="view.html" type="text/ng-template">
    <ion-view view-title="Second page">
      <ion-content class="padding">
          <h3>First Name: {{input.firstName}}, Last Name: {{input.lastName}}</h3>
          <button class="button button-full button-positive" ng-click="getData()">
            Get Data From Authorization Factory
          </button>          
      </ion-content>
    </ion-view>
  </script>   
  
</body>
 
</html>
JavaScript
var nameApp = angular.module('starter', ['ionic', 'ui.router']);

nameApp.config(function($stateProvider, $urlRouterProvider) {
 
  $stateProvider
    .state('list', {
      url: '/',
      templateUrl: 'list.html',
      controller: 'ListCtrl'
    })
    .state('view', {
      url: '/view',
      templateUrl: 'view.html',
      controller: 'ViewCtrl'
    });
 
  $urlRouterProvider.otherwise('/');
 
});

nameApp.factory('Authorization', function () {

    var authorization = {};

    return {
        getAuthObject: function () {
            return authorization;
        },
        setAuthObject: function (authObject) {
            authorization = authObject;
        }
    };
});

nameApp.controller('ListCtrl', function($scope, Authorization) {
  
  $scope.input = {};  
  
  $scope.$watch('input', function (newValue, oldValue) {
      if (newValue !== oldValue) Authorization.setAuthObject(newValue);
  }, true);  
});
 
nameApp.controller('ViewCtrl', function($scope, Authorization) {

  $scope.input = {};  

  $scope.getData = function(){
    $scope.input = Authorization.getAuthObject();
  }  
});

Overview

This solution also uses Factory service as data storage and two controllers as an example. Current Factory service is also different than the previous one:

nameApp.factory('Authorization', function () {

    var authorization = {};

    return {
        getAuthObject: function () {
            return authorization;
        },
        setAuthObject: function (authObject) {
            authorization = authObject;
        }
    };
});

In this example, factory service uses getter and setter functions to acquire/modify inner object called authorization. If input elements values are modified that change will be propagated to $scope.input object. At the same time application is watching that same object looking for changes:

  $scope.$watch('input', function (newValue, oldValue) {
      if (newValue !== oldValue) Authorization.setAuthObject(newValue);
  }, true);  

The watch() function creates a watch of some variable. When you register a watch you pass two functions as parameters to the $watch() function. First one is a value function we’re watching and the second one is a listener function. The listener function should do whatever it needs to do if the value has changed. It also accepts newValue and oldValue as parameters.

We can compare these parameters and if there’s a difference between them we will send changed value (in our case object) to Factory service. Notice one more thing, watch() function also accepts a third boolean parameter. This third parameter is used only if we’re comparing objects, you don’t need it if you’re watching primitive variables.

Next page has only one button:

<button class="button button-full button-positive" ng-click="getData()">
    Get Data From Authorization Factory
</button>

When cliked this button will trigger function getData(), which will in result retrieve authorization object from a Factory service and set it to $scope.input variable.

$scope.getData = function(){
    $scope.input = Authorization.getAuthObject();
} 

You don’t need to use click event, anything can server as a trigger.

Sharing Data During Page Transitions

Sometimes we only need to pass data between controllers. This data does not need to be remembered, only processed on successful page transition. Excellent example would be Master-Detail pattern where Master list point to Detail page holding only selected list element data (usually expanded data set not seen on a list element). If you want to find out more about this structure pattern take a look at one of my previous tutorials.

Example

Demo

Embeded working example
Ionic Master Detail Pattern

I will not talk about this example here. Read my previously mentioned tutorial (Tutorial 5 – Master Detail Pattern) if you want to find more.

Who Am I?

Between working as a senior Java developer in one of the largest insurance companies in the world and traveling, in my free time, I work as a professional mobile development adviser. I'm also a major jQuery Mobile supporter back at StackOverflow and a forum moderator at the official Ionic Framework forum.



Categories

19 thoughts on “Ionic Framework | How To Pass Data Between Pages”

  1. Thank you for the excellent tutorial. As a beginner to Angular & Ionic, I found your statement that tutorials never cover data passing is true!

  2. Great tutorial, thanks! One thing you may want to add would be how to pass data from a button? Like if I have one button named “Foo” and another named “Bar” and want to capture which button was pushed…

    Thanks again!

  3. I guess I am missing something here (sorry it’s typical).. but how do you do this with two actual pages, as in separate? I have a typical MVC .net project with the usual home.cshtml page and an about.schtml page just to try this and it is not working…

  4. Hi, I tried this approach but when I click the button to go to the next page, only the url changes. The actual page doesn’t change. Any idea what I did wrong?

  5. I want some text from a database to be shown on all pages of ionic 2 like emp id , po nuber , item , some thing like this on all my pages all

  6. I m only getting ‘Back’ text on screen … Does it require any plugin or other files like list and view .html in some directory

Leave a Reply