Using the same modal in multiple views is removing it


#1

Hi all. I’m working on a social app based on pictures, and I’m using a modal to load the image in fullscreen mode. I can open it from multiple views, but there is an error in this case: opening an image in profile view apparently calls modal.remove() when I open an image in feed view, so I can’t open any image at all in feed -I still can open them in profile-. It just happens in that way, not the other way around, and this thing doesn’t happen with other views related to the images. The error I get from the JS console is Cannot call modal.show() after remove(). Please create a new modal instance., but I’m never calling modal.remove()

Any ideas of the cause of this error? I’m like crazy and have found nothing yet. Thanks a lot.

Here is the code for the controllers of the views and the modal template:

feed-controller.js

angular.module('app.controllers')

.controller('feedCtrl', function($scope, $timeout, $ionicModal, $ionicPopup, $controller, $state, store, feedService, sharePostService, promotionService){
  $ionicModal.fromTemplateUrl('templates/post_detail.html', {
    scope: $scope,
    animation: 'slide-in-up'
  }).then(function(modal){
    $scope.modal = modal;
  });
  $scope.login_required = true;
  $scope.page = 1;
  $scope.post_pks = [];
  $scope.refresh_finished = false;
  $scope.no_more_peeks = false;
  $controller('utilsCtrl', { $scope: $scope });

  $scope.refreshFeed = function(){
    $scope.page = 1;
    $scope.post_pks = [];
    $scope.refresh_finished = false;
    $scope.no_more_peeks = false;
    feedService.getFeed($scope.page).then(
        function(data){
          for (var item in data.data){
            $scope.post_pks.push(data.data[item].pk);
            data.data[item].total_description = data.data[item].description
            if (data.data[item].description.length > 50){
              data.data[item].description = data.data[item].description.substring(0, 47)+"..."
            }
          };
          $scope.feed = data;
          $scope.user_pk = store.get("user_pk");
        }, function(error){
        }).finally(function(){
      $scope.refresh_finished = true;
      $scope.$broadcast('scroll.refreshComplete');
    });
  };
  

 $scope.loadMore = function(){
  if ($scope.refresh_finished && !$scope.no_more_peeks) {
    $scope.page += 1;
    $scope.no_more_peeks = false;
    feedService.getFeed($scope.page).then(
      function(data){
        if (data.data.length == 0) {
          $scope.no_more_peeks = true;
        }
        for (var item in data.data){
          if ($scope.post_pks.indexOf(data.data[item].pk) == -1) {
            data.data[item].total_description = data.data[item].description
            if (data.data[item].description.length > 50){
              data.data[item].description = data.data[item].description.substring(0, 47)+"..."
            }
            $scope.post_pks.push(data.data[item].pk);
            $scope.feed.data.push(data.data[item]);
          }
        };
      }, function(error){console.log(error)}).finally(function(){
        $scope.$broadcast('scroll.infiniteScrollComplete');
      });
    }
  };

$scope.checkMorePeeks = function(){
  $scope.no_more_peeks = false;
}

  $scope.$on('modal.hidden', function() {
    $scope.refreshFeed(); // pending update only the modified image
  });
  $scope.$on('$ionicView.enter', function() {
    $scope.refreshFeed(); // pending update only the modified image
  });
  // TODO: Remove modal to avoid memory leaks if required.

})

profile-controller.js

angular.module('app.controllers')

.controller('profileCtrl', function($scope, $cordovaCamera, $ionicModal, $ionicPlatform, $controller, $state, $ionicLoading, $ionicPopup, $ionicHistory, store, userDataService, profileInformationService, feedService, followService, notificationService){
  $ionicModal.fromTemplateUrl('templates/post_detail.html', {
    scope: $scope,
    animation: 'slide-in-up'
  }).then(function(modal){
    $scope.modal = modal;
  });
  $controller('utilsCtrl', { $scope: $scope });
  $scope.login_required = true;
  $scope.peeks_page = 1;
  $scope.keeps_page = 1;
  $scope.peeks_pks = [];
  $scope.keeps_pks = [];
  $scope.refresh_finished = false;
  $scope.no_more_peeks = false;
  $scope.no_more_keeps = false;
  $ionicHistory.clearHistory();
  $scope.upload = {};
  $scope.profile = {followers: 0, following: 0};
  $scope.indicator = 'peeks';
  $scope.following = null;
  $scope.peeks_quantity = 0;
  $scope.keeps_quantity = 0;
  $scope.upload.profilePicture = null;
  $scope.refreshFeed = function(){
    $scope.peeks_page = 1;
    $scope.keeps_page = 1;
    $scope.peeks_pks = [];
    $scope.keeps_pks = [];
    $scope.refresh_finished = false;
    $scope.no_more_peeks = false;
    $scope.no_more_keeps = false;

    $scope.charity = store.get('charity_name');
    $scope.charityCountry = store.get('charity_country');
    $scope.charityLogo = store.get('charity_logo');
    $scope.delta_wallet = parseFloat(store.get('delta_wallet'));
    $scope.delta_charity = parseFloat(store.get('delta_charity'));
    if ($scope.delta_wallet < 0) {$scope.delta_wallet_color = "color:#ff0000"};
    if ($scope.delta_wallet > 0) {$scope.delta_wallet_color = "color:#00ff00"};
    if ($scope.delta_wallet == 0) {$scope.delta_wallet_color = "color:#663366"};
    if ($scope.delta_charity < 0) {$scope.delta_charity_color = "color:#ff0000"};
    if ($scope.delta_charity > 0) {$scope.delta_charity_color = "color:#00ff00"};
    if ($scope.delta_charity == 0) {$scope.delta_charity_color = "color:#663366"};
    $scope.charity_money_raised = parseFloat(store.get('charity_money_raised'));
    userDataService.getUserData().then(function(user){
      $scope.user = user;
      $scope.wallet = parseFloat(store.get('wallet'));
      feedService.getPosts($scope.user.username, $scope.peeks_page).then(
        function(response){
          $scope.peeks_quantity = response.data.length;
          $scope.feed = organize_posts(response, 'peeks');
          profileInformationService.getProfileInfo(user.username).then(
            function(data){
              $scope.profile = data.data;
              feedService.getKeeps($scope.keeps_page).then(
                function(keeps){
                  $scope.keeps_quantity = keeps.data.length;
                  keeps = organize_posts(keeps, 'keeps');
                  $scope.feed.data = $scope.feed.data.concat(keeps.data);
                  followService.getFollowingList().then(
                    function (list) {
                      $scope.following = list.data;
                      followService.getFollowers($scope.user.username).then(
                      function(data){
                        $scope.followers = data.data;
                      }, function(error){
                        console.log(error);
                      });
                    },function(error){
                      console.log(error)
                    } 
                  );
                });
            });
        }
        );
    }, function(error){
      $state.go('login');
    }).finally(function(){
      $scope.refresh_finished = true;
      $scope.$broadcast('scroll.refreshComplete'); 
    });
  };

  $scope.$on('$ionicView.enter', function(){
    $scope.refreshFeed();
  });

 $scope.loadMorePeeks = function(){
  if ($scope.indicator=='peeks' && $scope.refresh_finished && !$scope.no_more_peeks) {
    $scope.peeks_page += 1;
    $scope.no_more_peeks = false;
    feedService.getPosts($scope.profile.username, $scope.peeks_page).then(
      function(data){
        if (data.data.length == 0) {
          $scope.no_more_peeks = true;
        }
        for (var item in data.data){
          if ($scope.peeks_pks.indexOf(data.data[item].pk) == -1) {
            data.data[item].total_description = data.data[item].description
            if (data.data[item].description.length > 50){
              data.data[item].description = data.data[item].description.substring(0, 47)+"..."
            }
            data.data[item].peeks = true
            $scope.peeks_pks.push(data.data[item].pk);
            $scope.feed.data.push(data.data[item]);
          }
        };
      }, function(error){console.log(error)}).finally(function(){
        $scope.$broadcast('scroll.infiniteScrollComplete');
      });
    }
  };

 $scope.loadMoreKeeps = function(){
  if ($scope.indicator=='keeps' && $scope.refresh_finished && !$scope.no_more_keeps) {
    $scope.keeps_page += 1;
    $scope.no_more_keeps = false;
    feedService.getKeeps($scope.keeps_page).then(
      function(data){
        if (data.data.length == 0) {
          $scope.no_more_keeps = true;
        }
        for (var item in data.data){
          if ($scope.keeps_pks.indexOf(data.data[item].pk) == -1) {
            data.data[item].total_description = data.data[item].description
            if (data.data[item].description.length > 50){
              data.data[item].description = data.data[item].description.substring(0, 47)+"..."
            }
            data.data[item].keeps = true
            $scope.keeps_pks.push(data.data[item].pk);
            $scope.feed.data.push(data.data[item]);
          }
        };
      }, function(error){console.log(error)}).finally(function(){
        $scope.$broadcast('scroll.infiniteScrollComplete');
      });
    }
  };

  organize_posts = function(items, variable){
  for (var item in items.data){
    if(variable == 'peeks'){
      $scope.peeks_pks.push(items.data[item].pk);
      items.data[item].peeks = true
    }else if(variable == 'keeps'){
      $scope.keeps_pks.push(items.data[item].pk);
      items.data[item].keeps = true
    }
    items.data[item].total_description = items.data[item].description
    if (items.data[item].description.length > 50){
      items.data[item].description = items.data[item].description.substring(0, 47)+"..."
    }
  };
  return items;
  }

  $scope.submit = function(){
    userDataService.updateUserData($scope.user).then(function(data){
      alertPopup = $ionicPopup.alert({
        title: 'Success',
        template: 'User data was updated.'
      });
      $state.go('tabsController.profile');
    }, function(error){
      alertPopup = $ionicPopup.alert({
        title: 'Error',
        template: 'Data could not be updated.'
      });
    });
  };

  $scope.openFileDialog = function(){
    $ionicLoading.show({
      templateUrl: 'templates/spinner.html'
    });
    $ionicPlatform.ready(function(){
      $ionicLoading.hide();
      navigator.CustomCamera.getPicture(function(imageData){
        $scope.user.profile_picture = imageData;
        $scope.$apply();
        userDataService.updateProfilePicture($scope.user.profile_picture).then(
          function(response){
            $scope.user.profile_picture = response.data.success;
          }, function(error){console.log(error)});
      }, function(){});
    });
    //ionic.trigger('click', { target: document.getElementById('profile-picture') }); 
  };

//  $scope.$watch("upload.profilePicture", function(newValue, oldValue){
//    if(newValue!=null && typeof newValue.name=='string'){
//      userDataService.updateProfilePicture(newValue).then(
//          function(response){
//            user.profile_picture = response.data.success;
//          });
//    }
//  });
  $scope.buttons = [{name: 'peeks',active: 'active'},{name: 'followers',active: ''},{name: 'following',active: ''},{name: 'keeps',active: ''}]

  $scope.activateButton = function(value) {
    i = 0;
    angular.forEach($scope.buttons, function(button)
    {   
        if( value == $scope.buttons[i].name)
        {
            $scope.buttons[i].active = 'active';
            $scope.indicator = value;
        }
        else
        {
            $scope.buttons[i].active = '';
        }
        i++;
    });
    i=0;
  };
  $scope.followUser = function(user_pk){
    followService.followUser(user_pk, 'create').then(
      function(data){
        $scope.profile.following += 1;
      }).finally(function(){
        $scope.refreshFeed();
      });
    };

  $scope.unfollowUser = function(user_pk){
    followService.followUser(user_pk, 'delete').then(
      function(data){
        $scope.profile.following -= 1;
      }).finally(function(){
        $scope.refreshFeed();
      });
    };
})

post-detail.html

<ion-modal-view title="{{ post.description }}" class="view-post-detail">
  <ion-pane class="transparent">
    <div class="fullscreen">
      <a class="button button-icon icon ion-close pull-right" ng-click="modal.hide()" style="margin: 15px"></a>
      <img ng-src="{{ post.picture }}" class="fullscreen">
      <div class="image-bar">
      	<div class="row">
      		<div class="col col-20 text-center">
      			<i ng-if="side_menu" href="#" ng-click="promotePost(true)" class="neutral button button-icon ion-arrow-up-c" ng-class="{'promote': post.promoted}"></i>Promote
      		</div>
          <div class="col col-10 text-center">
            <span ng-if="post.promoted==true||post.promoted==false"style="font-size:12px">{{ post.promotes - post.demotes }}</span>
          </div>
      		<div class="col col-20 text-center">
      			<i ng-if="side_menu" href="#" ng-click="promotePost(false)" class="neutral button button-icon ion-arrow-down-c" ng-class="{'demote': post.promoted === false}"></i>Demote
      		</div>
      		<div class="col col-25 text-center">
      			<span style="font-size:12px">{{ post.total_shares }}</span><i ng-if="side_menu" href="#" ng-click="sharePost(post.pk)" class="neutral button button-icon ion-ios-paperplane-outline" ng-class="{'promote': post.shared_by_user}"></i>Spread
      		</div>
          <div class="col col-25 text-center">
            <span style="font-size:12px">{{ post.comments.length }}</span><i ng-if="side_menu" href="#" ng-click="openComments()" class="neutral button button-icon ion-ios-chatbubble-outline"></i>Comment
          </div>
      	</div>
      </div>
    </div>
  </ion-pane>
</ion-modal-view>

Please tell me if more code is needed. Thanks.


#2

I was disabling cache in profile view, it seems doing that interferes with the modal. I removed the cache-view=false and it worked again. Thanks.