1

This is my factory:

.factory('userService',()){
  var user = {};
  return {

  getFirstname : function () {
    return user.firstname;
  },

  setFirstname : function (firstname) {
    user.firstname = firstname;
  }

}

And I'm using this service in my two controllers MainCtrl and AccountEditCtrl I'm using my getFirstname() in my MainCtrl and setFirstname in AccountEditCtrl

.controller('MainCtrl',['userService', function(userService){
  $scope.userName = userService.getFirstName();
}]);

.controller('AccountEditCtrl',['userService', function(userService){
      userService.setFirstname("New First Name");
}]);

My problem is that when I use the userService.setFirstname() the $scope.userName don't change in MainCtrl.

devadnqpnd
  • 154
  • 1
  • 3
  • 16
  • `$scope.userName = userService.getFirstName();` only gets called once when processed by the view. You have to update the view after a change. Maybe try `$watch` – frhd Apr 21 '15 at 10:41
  • can you tell me where will I put $watch?? – devadnqpnd Apr 21 '15 at 10:44
  • Please look here to get a better understanding: http://stackoverflow.com/a/15113029/2491198 – frhd Apr 21 '15 at 10:46
  • also for an example of how to "share" variables across controllers: http://stackoverflow.com/questions/29757442/sharing-subtotal-across-controllers-in-angular/29757627#29757627 – Dominic Scanlan Apr 21 '15 at 10:48
  • Yup I think I know what $watch is but I don't know what to watch. Should I watch $scope.userName or the user.firstname in the Factory? – devadnqpnd Apr 21 '15 at 10:50
  • Can I use $emit ?? because here AccountEdit is a child of MainCtrl – devadnqpnd Apr 21 '15 at 10:51

6 Answers6

10

In some case $watch is not working with factory object. Than you may use events for updates.

 app.factory('userService',['$rootScope',function($rootScope){
  var user = {};
  return {

  getFirstname : function () {
    return user.firstname;
  },

  setFirstname : function (firstname) {
    user.firstname = firstname;
    $rootScope.$broadcast("updates");
  }

}
}]);
app.controller('MainCtrl',['userService','$scope','$rootScope', function(userService,$scope,$rootScope) {
  userService.setFirstname("bharat");
  $scope.name = userService.getFirstname();
  $rootScope.$on("updates",function(){
    $scope.name = userService.getFirstname();
  });
}]);

app.controller('one',['userService','$scope', function(userService,$scope) {
  $scope.updateName=function(){
    userService.setFirstname($scope.firstname);
  }
}]);

Here is a working example

Bharat Bhushan
  • 2,077
  • 2
  • 21
  • 34
1

When using same object across controllers ,you have to define your service using the .service method like below:

.service('userService',function(){
  this.user = {};

  this.getFirstname = function () {
    return this.user.firstname;
  };

  this.setFirstname = function (firstname) {
    this.user.firstname = firstname;
  };

});
manasi sakhare
  • 1,051
  • 7
  • 18
  • thank you for your answer, I already solved my problem. My problem is not in my controller anymore it's in my view -.- – devadnqpnd Apr 21 '15 at 13:22
1

Use $timeout for broadcast event. it will help you.

app.factory('userService',['$rootScope', "$timeout", function($rootScope, $timeout){
var user = {};
return {

getFirstname : function () {
    return user.firstname;
},

setFirstname : function (firstname) {
    user.firstname = firstname;
    $timeout(function(){
        $rootScope.$broadcast("updates");
    }, 1000)
}

}
}]);
app.controller('MainCtrl',['userService','$scope','$rootScope', function(userService,$scope,$rootScope) {
userService.setFirstname("bharat");
$scope.name = userService.getFirstname();
$rootScope.$on("updates",function(){
    $scope.name = userService.getFirstname();
});
}]);

app.controller('one',['userService','$scope', function(userService,$scope) {
$scope.updateName=function(){
    userService.setFirstname($scope.firstname);
}
}]);
Subhash Kumar
  • 286
  • 2
  • 10
0

You have two options to overcome this problem.

Solution 1st:

Adding a watch in your controller.

.controller('MainCtrl',['userService', function(userService) {

    $scope.userName = userService.getFirstName();

    $scope.$watch(function() {
        return userService.getFirstName();
    }, function(newValue) {
       $scope.username = newValue;
    });
}]);

Solution 2nd:

.controller('MainCtrl',['userService', function(userService) {

    $scope.getUsername = function() {
        userService.getFirstName();
    };

}]);

Now your view should directly call this function.

<div class="username">{{getUsername()}}</div>

Now, according to Angular's doc, whenever the return value from a function call changes, Angular will update the values in the view.

Shashank Agrawal
  • 25,161
  • 11
  • 89
  • 121
0

sample factory with getter and setter example code

<div ng-app="myApp">
<div ng-controller="FirstCtrl">
  <br>Input is : <strong>{{data.firstName}}</strong>
  <button ng-click="setData()">setData</button>
</div>
<hr>

<div ng-controller="SecondCtrl">
  Input should also be here: {{data.firstName}}
  <button ng-click="getData()">getData</button>
</div>
</div>

var myApp = angular.module('myApp', []);

myApp.factory('Data', function(){

    var service = {
        FirstName: '',
        setFirstName: function(name) {
            // this is the trick to sync the data
            // so no need for a $watch function
            // call this from anywhere when you need to update FirstName
            angular.copy(name, service.FirstName); 
        }
    };
    return service;
});


// Step 1 Controller
myApp.controller('FirstCtrl', function( $scope, Data ){
$scope.setData = function() {
        Data.FirstName='Tridip';
    };
});

// Step 2 Controller
myApp.controller('SecondCtrl', function( $scope, Data ){
    $scope.FirstName = Data.FirstName;

$scope.getData = function() {
        alert('get data '+Data.FirstName)
    };
});
Monojit Sarkar
  • 2,353
  • 8
  • 43
  • 94
-1

you should use $ watch so:

.factory('userService',()){
  return {
     user:{ 'firstname': 'defaultFirstname'},
     getFirstname : function () {
       return user.firstname;
     },

     setFirstname : function (firstname) {
       user.firstname = firstname;
     }
}
.controller('MainCtrl',['userService', function(userService){
  $scope.userName = userService.getFirstname();
  $scope.$watch('userService.user.firstname', function (newVal) {
      $scope.userName = newVal;
  });
}]);

.controller('AccountEditCtrl',['userService', function(userService){
      userService.setFirstname("New First Name");
}]);