1

I am a newbie for AngularJS so maybe I am looking at this the wrong way. If so, please point me in the right direction.

Basically I want to update some DOM elements that reside in another controller in another module. I am trying to send data through a service but it seems that it is not updated on the destination scope.

var mainModule = angular.module('main', []);
var appModule = angular.module('app', ['main']);


appModule.controller("appCtrl", function ($scope, $routeParams, mainService) {

    $scope.mainService = mainService;

    var initialize = function () {
        $scope.mainService.currentID = $routeParams.productId;
    }

    initialize();
});


mainModule.factory('mainService', function () {
    var mainService = { currentID: 0 };
    return mainService
});

mainModule.controller('mainCtrl', ['$scope', 'mainService', function ($scope, mainService) {

    $scope.mainService = mainService;
    $scope.function1Url = "function1/" + $scope.mainService.currentID;
    $scope.function2Url = "function2/" + $scope.mainService.currentID;
    //CurrentID is always 0!!
}]);

I expect that when calling the initialize() function in the appCtrl, it will see the currentID param in the service which is also used by the mainCtrl.

1
  • You forgot to inject $routeParams Commented Nov 2, 2015 at 15:54

2 Answers 2

2

For updating controller using service, I strongly recommend you to use $rootScope.$broadcast and $rootScope.$on. Here is an example of how you can do it, and link to a blog:

$rootScope.$broadcast('myCustomEvent', {
  someProp: 'Sending you an Object!' // send whatever you want
});

// listen for the event in the relevant $scope
$rootScope.$on('myCustomEvent', function (event, data) {
  console.log(data); // 'Data to send'
});

http://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/

Here is your working solution:

var mainModule = angular.module('main', []);
var productModule = angular.module('product', ['main']);

productModule.service('mainService', ['$rootScope', '$timeout', function ($rootScope, $timeout) {
    this.method1 = function () {
      alert('broadcast');
           $rootScope.$broadcast('myCustomEvent', {
                newValue: 'This is an updated value!' 
            });
    }
}]);

productModule.controller('mainCtrl', ['$scope', '$rootScope', function ($scope, $rootScope){

    $scope.myValue = 'Initial value';

     $rootScope.$on('myCustomEvent', function (event, data) {
        $scope.myValue = data.newValue;
        alert('received broadcast');
    });

}]);

productModule.controller("productCtrl", function ($scope, mainService) {

    $scope.mainService = mainService;
    $scope.clickMe = 'Click to send broadcast';

    $scope.callService = function () {
      $scope.clickMe = 'Broadcast send!';
       $scope.mainService.method1();
    }


});

And HTML:

  <body ng-app='main'>
    <div  ng-controller="mainCtrl"><b>My value:</b>{{myValue}}</div>

    <div  id="product" ng-controller="productCtrl">
      <button ng-click="callService()">{{clickMe}}</button>
    </div>

    <script type="text/javascript">angular.bootstrap(document.getElementById("product"), ['product']);</script>
  </body>
Sign up to request clarification or add additional context in comments.

4 Comments

Beware of $rootScope.$broadcast this will send to all scopes (performance). Use $scope.$emit if what you need to notify is above you. Or $scope.$broadcast if it's a child of you.
I have tried the $rootScope.$broadcast but it seems it is never received. I have set up a Plunker to demonstrate the problem. Plunker link
I think - I am not 100% sure that two different ng-app's have two different $rootScopes - hence, you could not pass events between them
ok, so this only works when using in the same ng-app. Are there other posibilities to communicate data between controllers from different ng-apps?
0

You have a couple different methods of doing this.

I agree with uksz, you should use broadcast/emit to let other scopes know of the change, let them handle as needed.

Broadcast goes to all child scopes of the element

$scope.$broadcast("Message Name", "payload, this can be an object"); 

Emit goes to all parent scopes of this element

$scope.$emit("message name", "payload, this can be an object"); 

Other option is you can also require the other controller

appModule.directive('myPane', function() {
  return {
    require: '^myTabs',
    scope: {},
    link: function(scope, element, attrs, tabsCtrl) {
      tabsCtrl.addPane(scope);
    }
  };
});

Lastly you can include a function on the scope so you can let the parent scope know what's going on

appModule.directive('myPane', function() {
  return {
    scope: {
      doSomething: '&something'
    },
    link: function(scope, element, attrs) {
      $scope.doSomething(test);
    }
  };
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.