title: ng-if not updating when $scope var changes in AngularJS
body: <p>In my view I have this:</p>
  
  <pre><code>&lt;div class="tab-loading-container" ng-if="mapStatus.loading =='true'"&gt;
      &lt;div class="tab-loading"&gt;Loading map&lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>In my controller I have:</p>
  
  <pre><code>$scope.mapStatus = {};
  </code></pre>
  
  <p>and then various functions that update the scope var used by the <code>ng-if</code>, when certain criteria are met, such as being offline etc (for example:</p>
  
  <pre><code>function enableMap () {
      $scope.mapStatus.loading = false;
  }
  </code></pre>
  
  <p>My issue is that although the scope var is getting changed correctly (confirmed with good 'ol console.log and angular chrome extension) the <code>ng-if</code> in the view never updates / gets added / removed to show / remove the div.</p>
  
  <p>I've tried using $apply (though my understanding of it isn't great), for example:</p>
  
  <pre><code>function enableMap () {
      $scope.$apply(function() {
          $scope.mapStatus.loading = false;
      });
  }
  </code></pre>
  
  <p>but that throws errors such as <code>Error: [$rootScope:inprog] $apply already in progress</code></p>
  
  <p>Feel like I'm missing something obvious :(</p>
  
  <hr>
  
  <p>More code as requested:</p>
  
  <pre><code>angular.module('app.case.controller', [])
  .controller('CaseController', function($rootScope, $scope, $state, $stateParams, $filter, casesFactory, $ionicActionSheet, $ionicModal, $ionicTabsDelegate, $ionicLoading, ConnectivityMonitor) {
  
  /// Other non related code
  
  // location map - refactor into a factory
      $scope.mapStatus = {};
  
      function initMap () {
          var pos = { 'lat':  52.6136149, 'lng': -1.1936672 };
  
          var latLng = new google.maps.LatLng(pos.lat, pos.lng);
  
          var mapOptions = {
              center: latLng,
              zoom: 15,
              mapTypeId: google.maps.MapTypeId.ROADMAP,
              fullscreenControl: false,
              mapTypeControl: false
          };
  
          $scope.map = new google.maps.Map(document.getElementById('map'), mapOptions);
  
          google.maps.event.trigger(map, 'resize');
  
          //Wait until the map is loaded
          google.maps.event.addListenerOnce($scope.map, 'idle', function () {
  
              enableMap();
  
              console.log('map loaded');
  
              var marker = new google.maps.Marker({
                  map: $scope.map,
                  animation: google.maps.Animation.DROP,
                  position: latLng
              });
  
              google.maps.event.trigger(map, 'resize'); 
  
              $scope.map.setCenter(latLng);
  
          });
      }
  
      function loadGoogleMaps () {    
          $scope.mapStatus.loading = true;
  
          // This function will be called once the SDK has been loaded
          window.mapInit = function(){
              initMap();
          };
  
          // Create a script element to insert into the page
          var script = document.createElement('script');
          script.type = 'text/javascript';
          script.id = 'googleMaps';
          script.src = 'https://maps.googleapis.com/maps/api/js?key=XXX&amp;callback=mapInit';
  
          document.body.appendChild(script);
      }
  
      function enableMap () {
          $scope.mapStatus.loading = false;
          $scope.mapStatus.offline = false;
      }
  
      function disableMap () {
          $scope.mapStatus.offline = true;
      }
  
      function checkLoaded () {
          if (typeof google == 'undefined"' || typeof google.maps == 'undefined') {
              loadGoogleMaps();
          } else {
              enableMap();
          }       
      }
  
      function addConnectivityListeners () {
  
          if (ionic.Platform.isWebView()) {
  
              // Check if the map is already loaded when the user comes online, if not, load it
              $rootScope.$on('$cordovaNetwork:online', function(event, networkState) {
                  checkLoaded();
              });
  
              // Disable the map when the user goes offline
              $rootScope.$on('$cordovaNetwork:offline', function(event, networkState) {
                  disableMap();
              });
  
          } else {
  
              //Same as above but for when we are not running on a device
              window.addEventListener("online", function(e) {
                  checkLoaded();
              }, false);    
  
              window.addEventListener("offline", function(e) {
                  disableMap();
              }, false);  
          }
      }
  
      function showMap () {
  
          console.log('showMap() called');
  
          if (typeof google == 'undefined' || typeof google.maps == 'undefined') {
  
              console.warn("Google Maps SDK needs to be loaded");
  
              disableMap();
  
              if (ConnectivityMonitor.isOnline()){
                  loadGoogleMaps();
              }
          }
          else {
              if (ConnectivityMonitor.isOnline()){
                  initMap();
                  enableMap();
              } else {
                  disableMap();
              }
          }
  
          addConnectivityListeners();
      }
  
      $scope.initMap = function () {
          showMap();
      };
  </code></pre>
  
  <p>To confirm the scope vars are being changed here's a screenshot from the AngularJS chrome extension:</p>
  
  <p><a href="https://i.stack.imgur.com/7P0wn.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/7P0wn.png" alt="enter image description here"></a></p>