In my view I have this:
<div class="tab-loading-container" ng-if="mapStatus.loading =='true'">
    <div class="tab-loading">Loading map</div>
</div>
In my controller I have:
$scope.mapStatus = {};
and then various functions that update the scope var used by the ng-if, when certain criteria are met, such as being offline etc (for example:
function enableMap () {
    $scope.mapStatus.loading = false;
}
My issue is that although the scope var is getting changed correctly (confirmed with good 'ol console.log and angular chrome extension) the ng-if in the view never updates / gets added / removed to show / remove the div.
I've tried using $apply (though my understanding of it isn't great), for example:
function enableMap () {
    $scope.$apply(function() {
        $scope.mapStatus.loading = false;
    });
}
but that throws errors such as Error: [$rootScope:inprog] $apply already in progress
Feel like I'm missing something obvious :(
More code as requested:
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&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();
    };
To confirm the scope vars are being changed here's a screenshot from the AngularJS chrome extension:

 
     
     
     
     
    