James M. Lay
James M. Lay

Reputation: 2470

$scope update across different modules on $http

How do I update one module's $scope member from another module's $http.success()?

This is going to be a tough one to explain, so I'll do my best.

I have two modules, HeaderApp and ContentApp. Essentially, HeaderApp controls the breadcrumbs and navigation heading the web app, and ContentApp is the "content", if you will.

For reasons I don't really want to get deep into, ContentApp has to refresh every 30 seconds or so to keep the information up to date.

These modules are almost completely independent of each other, except that every time ContentApp refreshes its data, a refresh_time timestamp needs to be updated in the header.

Here's one variation of what I've tried:

html

<div ng-app="HeaderApp">
    <div ng-controller="Header">
        <span> Updated: {{refresh_time}} </span>
    </div>
</div>

<div ng-app="ContentApp">
    <div ng-controller="Content">
        <div ng-repeat="row in data"> {{row.content}} </div>
    </div>
</div>

javascript

var HeaderApp = angular.module("HeaderApp", [])
.controller("Header", ['$scope', function($scope) {
    $scope.refresh_time = new Date().toString();
    window.update_refresh_time = function() {
        $scope.refresh_time = new Date().toString();
        $scope.$apply(); //this is throwing an error in console
    }
}]);

var ContentApp = angular.module("ContentApp", [])
.controller("Content", ['$scope', '$http', '$timeout', function($scope,$http,$timeout) {
    (function repeatMe() {
        
        $http(...)
        .success(function(data) {

            $scope.data = data;
            window.update_refresh_time();
            $timeout(repeatMe, 30000);

        }).error(...);
    })();
}]);

//manual bootstrapping...
angular.element(document).ready(function () {
    angular.bootstrap(document, ['HeaderApp', 'BUOverviewApp']);
});

Other variations I've tried (after reading other posts on SO) include sharing a factory service across the modules via angular.module("ContentApp", ["HeaderApp"]) and employing $rootScope.

When I check the javascript console, I get three consecutive errors that look like this. I read the entire page and it didn't really make sense. When I read other comments regarding the appropriate time to use $apply(), it seems to me like any time you get this already in progress error is a time that it should theoretically be unnecessary to invoke it in the first place.

Upvotes: 1

Views: 53

Answers (2)

alexreardon
alexreardon

Reputation: 636

Have you tried $rootScope.broadcast()?

Upvotes: 1

GillesC
GillesC

Reputation: 10874

Use $rootScope.$on and $rootScope.$broadcast and I don't think apply() is needed here, it will fire error if used when it shouldn't be.

var HeaderApp = angular.module("HeaderApp", [])
.controller("Header", ['$scope', '$rootScope', function($scope, $rootScope) {
    $scope.refresh_time = new Date().toString();
    $rootScope.$on("refresh_time", function() {
        $scope.refresh_time = new Date().toString();
    });
}]);

var ContentApp = angular.module("ContentApp", [])
.controller("Content", ['$scope', '$rootScope', '$http', '$timeout', function($scope,$rootScope,$http,$timeout) {
    (function repeatMe() {

        $http(...)
        .success(function(data) {

            $scope.data = data;
            $rootScope.$broadcast("refresh_time");
            $timeout(repeatMe, 30000);

        }).error(...);
    })();
}]);

Upvotes: 1

Related Questions