Ionic Ion-List is Not Updating After Item is Being Added

I am trying to add a new item to the Ion-List and for some reason it never refresh to update the list:

.controller("HomeController",function($scope,$ionicModal,$state){

    $scope.windows = [{id : 1,title:"hello"}];

    $scope.addNewWindow = function(window) {
      // assign a new id to the window
      $scope.windows.push(window);
      // close the modal
      $scope.closeAddNewWindowModal();
    }

I have debugged it and $scope.windows is updated and it does show multiple items But for some reason the ion-list is never updated.

Here is the Index.html code:

<body ng-app="starter" ng-controller="HomeController">

    <ion-pane>
      <ion-header-bar class="bar-positive">
        <h1 class="title">MI</h1>

        <div class="buttons">
          <button ng-click="openAddNewWindowModal()" class="button">Add New Window</button>
        </div>
      </ion-header-bar>

      <ion-nav-view class="has-header"></ion-nav-view>

    </ion-pane>

  </body>

list.html looks like this:

<ion-list>
  <ion-item ui-sref="window-details" ng-repeat="window in windows">
    {{window.title}}
  </ion-item>
</ion-list>

Here is the complete code:

// Ionic Starter App

// angular.module is a global place for creating, registering and retrieving Angular modules
// ‘starter’ is the name of this angular module example (also set in a attribute in index.html)
// the 2nd parameter is an array of 'requires’
angular.module(‘starter’, [‘ionic’])

.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);

  // Don't remove this line unless you know what you are doing. It stops the viewport
  // from snapping when text inputs are focused. Ionic handles this internally for
  // a much nicer keyboard experience.
  cordova.plugins.Keyboard.disableScroll(true);
}
if(window.StatusBar) {
  StatusBar.styleDefault();
}

});
})

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

  $stateProvider
  .state('list',{
    url: '/list',
    templateUrl:'templates/list.html',
    controller: 'HomeController',
  })
  .state('window-details',{
    url: '/window/:windowId',
    templateUrl: 'templates/window-details.html',
    controller: 'HomeController'
  })

  $urlRouterProvider.otherwise('list');

})

// Controllers

.controller(“WindowDetailsController”,function($scope){

})

.controller(“HomeController”,function($scope,$ionicModal,$timeout){

$scope.windows = [{id : 1,title:"hello"}];

$scope.addNewWindow = function(window) {
  // assign a new id to the window
  $scope.windows.push(window);
  // close the modal
  $scope.closeAddNewWindowModal();
  $timeout(function(){});
}

$scope.openAddNewWindowModal = function() {

  $ionicModal.fromTemplateUrl('templates/add-new-window-modal.html',{
    scope: $scope,
    animation: 'slide-in-up'
  }).then(function(modal){
    $scope.modal = modal;
    // show the modal
    $scope.modal.show();
  });

  // close the modal
  $scope.closeAddNewWindowModal = function() {
    $scope.modal.hide();
  }
}

})

My guess is the code running from openAddNewWindowModal is not triggering a digest or your controller code. To try to force the digest, do this in your addNewWindow call:

controller('HomeController', function(..., $timeout) {
$scope.addNewWindow = function(window) {
  $scope.windows.push(window);
  $scope.closeAddNewWindowModal();
  $timeout(function() {}};
};

Thanks! The problem I am facing is that even though I add new items to $scope.windows, ion-list has no idea that the items are added and it does not show the newly added items once the modal is closed.

Yes, and this is what I’m referring to in my response. You need to trigger a digest so it knows that the items have changed. Did you try the code above?

If that doesn’t work, add some console logs to addNewWindow to verify it’s even being called from the modal.

Thanks! Adding $timeout did not work. No errors on console. I pasted the complete code in the original question.

Not sure what’s going on. Add some console logs into your addNewWindow to see if it’s being called.

Possibly a bug in Ionic framework. I even went with a simpler route and called openModal() from ng-click. The openModal is called I can debug it but the modal never appears on the screen.

.controller(“HomeController”,function($scope,$ionicModal){

// initialize the modal
$ionicModal.fromTemplateUrl(‘templates/add-new-window-modal.html’,{
scope: $scope,
animation: ‘slide-in-up’
}).then(function(modal){
$scope.modal = modal;
});

$scope.openModal = function() {
$scope.modal.show();
}

As, you can see in the above code I am initializing the $ionicModal inside the controller. I then call the openModal from my HTML and I can see it enters the function and calls $scope.modal.show() but the modal never appears on the screen.

<div class="buttons">
      <button ng-click="openModal()" class="button">Add New Window</button>
    </div>

Any chance you can share a quick demo? Via codepen perhaps?

Thanks! I have uploaded the project in Dropbox:

https://dl.dropboxusercontent.com/u/20116434/ICR.zip

That’s not quite the same as building a simple demo and sharing it on CodePen. Just FYI. :wink:

I am using multiple html files which Codepen does not support.

Right - but part of debugging sometimes means building a smaller test case to help focus on the issue at hand.

Just a suggestion for next time. I have your code running and can recreate the issue.

I built a new app and mimicked a lot of yours and was not able to reproduce the bug - yet I can consistently reproduce it in yours. I can confirm your code that is run when the new window is added is fired, so that’s fine. I can confirm $scope.windows grows by one item. Yet nothing I can do will force the view to update the display. I tried various combinations, but nothing worked.

WOW! Thanks a lot for testing it out. Do you think it is a bug in the framework? How will one developer know at this point that he/she needs to discard the app and try again from scratch? This is kinda insane!

Honestly I think it is a Scope issue - the #1 thing that bugs me with Angular. I’d be willing to bet we are doing something wrong and this is not a bug - but I’m not convinced of course.

Thanks a lot for your help!

This kinda scares me that we can spend days debugging an issue only to find out that the issue exists in Angular or Ionic framework.

To be clear - I’m still thinking it is going to be our fault.

Thanks! We are currently evaluating frameworks for large mobile applications. Ionic was my first choice but now we really need to think about it.

Ok, so I’ve discovered something. As I said, I did a simple test and it worked fine. As soon as you stop using routing and the state provider, it works. So something about that is breaking things.

Getting more close. I added a button to the view itself that calls the modal open. When I do that, things work perfectly. I can just $scope.push, no timeout, etc. So calling the modal from the header is part of the issue.

If I had to guess, this line:
body ng-app=“starter” ng-controller="HomeController"
Is “confusing” Angular in terms of what controller is active, etc.

I’m kinda making crap up now, but I think that might be it.