6

EDIT: Working plunker: http://plnkr.co/edit/iInh7TnbGvSHSPOWuWPk?p=preview

====================================================================

In the following plunker: http://plnkr.co/edit/TIfkYE?p=preview

A very simple example compares the usage of a factory and a service. Two way data-binding works using the service but not the factory. Why?

With the service:

<button btn-radio="item.nb" ng-model="fromService.current>

clicking the button correctly updates the property current of the service fromService.

However, using a factory:

<button btn-radio="item.nb" ng-model="fromFactory.current>

clicking the button does not update the property current of the factory fromFactory.

My use case is the following: I want to use a service/factory to share data across controllers and other services.

I have read a lot references, including:

Community
  • 1
  • 1
apairet
  • 3,120
  • 16
  • 21

2 Answers2

8

The problem is var current is a primitive and when you initialize the object using it as a value, it will not create a reference to intial variable, the object property will just take it's value.

WIthin your isCurrent function you are then making comparison to the original variable, which never changes. The current property however is changed by the 2 way binding you created with ng-model

Simple example ( can paste this in your browser console to confirm):

var current=0;
var obj={
  current: current
}

current=10;
alert(obj.current)// hasn't changed, is still 0

To fix your factory you need to make your comparisons to the object returned from factory

myApp.factory('fromFactory', function() {
  console.log("factory is called");
    var current = 0;
    return {
        current: current,
        isCurrent: function (nb) {

           /* change return nb === current;*/

          /* compare to the object version of "current" which is bound to ng-model*/
          return nb === this.current;
          },
        printCurrent: function () {
          console.log("print fromFactory", this.current);
        }
    };
});
charlietfl
  • 164,229
  • 13
  • 110
  • 143
2

Another Solution is to construct an object and return it:

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

    console.log("factory is called");

    var exports = {};
    exports.current = 0;
    exports.isCurrent = function (nb) {
          return nb == exports.current;
    };
    exports.printCurrent = function () {
        console.log("print fromFactory", exports.current);
    };

    return exports;
});

Both this and charlietfl solutions work perfectly. Working plunker: http://plnkr.co/edit/iInh7TnbGvSHSPOWuWPk?p=preview

apairet
  • 3,120
  • 16
  • 21
  • 1
    this returns same thing, just different syntax adding properties to object `return {}` means return object – charlietfl Dec 27 '13 at 13:57