Modal works with "serve" correctly, but it doesn't after building project

Hello fellow Ioners…

I’m pulling my hair off because of this problem. The modal is working fine, veeery fine while I’m developing using this command:

ionic run --device --livereload -c -s --debug

When I decided to build the app and test it without the server running. The modal just doesn’t work. Nothing happens, as if the modal was not created/instantiated.

I use this command to build:

ionic build ios

I’ve also tried:

ionic build ios --debug

and

ionic build ios --release

Tried the build on actual devices (iPhone 5) with different iOS versions (iOS 7 & iOS 8). Tried the simulator… same thing… modal not working.

Here’s my code:
I have the modal in a separate file:

/templates/settings.html

Here’s my controller:

.controller('Main', function($scope, $ionicModal, AuthService) {


  $ionicModal.fromTemplateUrl('/templates/settings.html', {
    scope: $scope,
    animation: 'slide-in-up',
    backdropClickToClose: true,
    hardwareBackButtonClose: true,
    focusFirstInput: true
  }).then(function(modal) {
    $scope.settingsModal = modal;
    console.log($scope.settingsModal);
  });


  $scope.openSettings = function() {
    console.log('Opening Settings');
    $scope.settingsModal.show();
  };

  $scope.hideSettings = function() {
    console.log('Hiding Settings');
    $scope.settingsModal.hide();
  };

And here’s my modal template:

<ion-modal-view>
  <!-- Settings header bar -->
  <ion-header-bar class="bar-secondary ml3b-bar">
    <h1 class="title">Settings</h1>
    <button class="button button-clear button-positive" ng-click="hideSettings()">Close</button>
  </ion-header-bar>

  <!-- Settings content area -->
  <ion-content class="padding">
  </ion-content>
</ion-modal-view>

Nothing fancy here.

The thing that really annoys me, is that I’ve started a new project with the template “tests”, and the modal there works just fine after building. So it must be something I’m doing “before” I’m loading the modal.

So… here’s my app.js:

angular.module('ml3b', ['ionic', 'ngMessages', 'ml3b.controllers', 'ml3b.services', 'ngCordova'])

.run(function($ionicPlatform,$rootScope,$localstorage,$q,$http, $cordovaPush, AuthService,$state) {
  console.log("####### App started #######");
  $rootScope.debugMode = false;
  Parse.initialize(***, ***);  //replaced intentionally
  console.log("####### Parse initialized #######");

  $ionicPlatform.ready(function() {
    console.log("####### App ready #######");

    console.log("AuthService", AuthService.checkLogin());

    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if (window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if (window.StatusBar) {
      // org.apache.cordova.statusbar required
      StatusBar.styleDefault();
    }
  });
})


.config(function($stateProvider, $urlRouterProvider) {

  $stateProvider

  // setup an abstract state for the tabs directive
    .state('tab', {
    url: "/tab",
    abstract: true,
    templateUrl: "templates/tabs.html"
  })

  // Each tab has its own nav history stack:

  .state('tab.bookings', {
    url: '/bookings',
    views: {
      'tab-bookings': {
        templateUrl: 'templates/tab-bookings.html',
        controller: 'BookingsCtrl'
      }
    }
  })

  .state('tab.games', {
      url: '/games',
      views: {
        'tab-games': {
          templateUrl: 'templates/tab-games.html',
          controller: 'GamesCtrl'
        }
      }
    })
    .state('tab.booking-detail', {
      url: '/bookings/:bookingId',
      views: {
        'tab-bookings': {
          templateUrl: 'templates/booking-detail.html',
          controller: 'BookingDetailCtrl'
        }
      }
    })
    .state('tab.game-detail', {
      url: '/games/:gameId',
      views: {
        'tab-games': {
          templateUrl: 'templates/game-detail.html',
          controller: 'GameDetailCtrl'
        }
      }
    });

  // if none of the above states are matched, use this as the fallback
  $urlRouterProvider.otherwise('/tab/bookings');

});

Help me :frowning:

Safari remote debugging got me this:

Error: 'undefined' is not an object (evaluating '$scope.createModal.show')
openCreateBooking@file:///var/mobile/Applications/BAEE6A64-0181-41DC-A034-25457C25B998/Ml3b.app/www/js/controllers.js:46:23
$parseFunctionCall@file:///var/mobile/Applications/BAEE6A64-0181-41DC-A034-25457C25B998/Ml3b.app/www/lib/ionic/js/ionic.bundle.js:20124:23
file:///var/mobile/Applications/BAEE6A64-0181-41DC-A034-25457C25B998/Ml3b.app/www/lib/ionic/js/ionic.bundle.js:50863:21
$eval@file:///var/mobile/Applications/BAEE6A64-0181-41DC-A034-25457C25B998/Ml3b.app/www/lib/ionic/js/ionic.bundle.js:22178:28
$apply@file:///var/mobile/Applications/BAEE6A64-0181-41DC-A034-25457C25B998/Ml3b.app/www/lib/ionic/js/ionic.bundle.js:22276:28
file:///var/mobile/Applications/BAEE6A64-0181-41DC-A034-25457C25B998/Ml3b.app/www/lib/ionic/js/ionic.bundle.js:50862:19
eventHandler@file:///var/mobile/Applications/BAEE6A64-0181-41DC-A034-25457C25B998/Ml3b.app/www/lib/ionic/js/ionic.bundle.js:10823:25
dispatchEvent@[native code]
triggerMouseEvent@file:///var/mobile/Applications/BAEE6A64-0181-41DC-A034-25457C25B998/Ml3b.app/www/lib/ionic/js/ionic.bundle.js:2811:20
tapClick@file:///var/mobile/Applications/BAEE6A64-0181-41DC-A034-25457C25B998/Ml3b.app/www/lib/ionic/js/ionic.bundle.js:2800:20
tapTouchEnd@file:///var/mobile/Applications/BAEE6A64-0181-41DC-A034-25457C25B998/Ml3b.app/www/lib/ionic/js/ionic.bundle.js:2918:13

It’s as I suspected. The modal is not created when the app is built.

any clue?

Ok, I’ve solved it…

All I’ve had to do is just remove the “/” from the start of the template URL. Meh.

Thanks to this topic: