Jester
Jester

Reputation: 3327

Angularjs retain local variable

I have a factory like this:

TestFactory= function () {
    var objectName=null;

    return {
        SetName:function(name) {
            objectName = name;
        },
        GetName:function() {
            return objectName;
        },
        Init:function() {
            return angular.copy(this);
        }
    }
}

A controller like:

TestController = function($scope) {
    $scope.TestClick = function () {

        var tstA = TestFactory.Init();
        var tstB = TestFactory.Init();

        tstA.SetName('test A')
        tstB.SetName('test B')

        console.log('A', tstA.GetName());
        console.log('B', tstB.GetName());

    }   
}

In the console I get Test B for both objects.

How can I make a proper instance of this object?

I would like to use the objectName value in other functions of the factory.

Upvotes: 2

Views: 132

Answers (4)

Stubbies
Stubbies

Reputation: 3124

You basically need to create a simple getter/setter.

angular.module('app', [])
  .controller('TestController', testController)
  .service('serviceFactory', serviceFactory);


testController.$inject = ['serviceFactory'];

function testController(serviceFactory) {

  serviceFactory.set('A', {
    name: 'test A'
  });

  serviceFactory.set('B', {
    name: 'test B'
  });

  console.log(serviceFactory.getAll());
  console.log(serviceFactory.get('A'));
  console.log(serviceFactory.get('B'));

}

function serviceFactory() {
  var 
  _model = {
    name: ""
  },
  _data = {};

  return {
    set: function(key, data) {
      _data[key] = angular.extend({}, _model, data);
    },
    get: function(key) {
      return _data[key];
    },
    getAll: function() {
      return _data;
    }
  }


}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>

<body ng-app="app" ng-controller="testController"></body>

Upvotes: 0

ChiefTwoPencils
ChiefTwoPencils

Reputation: 13930

Services and factories are singletons so I think you can achieve what you want with a more appropriate use of the factory by providing an Init function that returns the common code and unique name like so:

angular.module('app')
       .factory('ServiceFactory', serviceFactory);

function serviceFactory() {
    return {
        Init: function (name) {
            return {
                objectName: name,
                setName: function (name) {
                    this.objectName = name;
                },
                getName: function () {
                    return this.objectName;
                }
            };
        }
    };
}

This leaves the possibility to use it as a factory that can initialize many types.

Upvotes: 1

jbrown
jbrown

Reputation: 3025

Couple of issues. First your returning an object rather than a function from your factory.

app.factory('TestFactory', function() {
  return function() {
    var objectName = null;

    var setName = function(name) {
      objectName = name;
    };

    var getName = function() {
      return objectName;
    };

    return {
      SetName: setName,
      GetName: getName
    };
  };

});

Then you can just instantiate like this:

var tstA = new TestFactory();
var tstB = new TestFactory();

Upvotes: 1

Manu Obre
Manu Obre

Reputation: 2304

Take into account that in Angular, Factories are singletons, so the instance is always the same.

You can do the following:

TestFactory= function () {
    var objectName={};

    return {
        SetName:function(property,name) {
            objectName[property] = name;
        },
        GetName:function(property) {
            return objectName[property];
        },
        Clear:function(property) {
            delete objectName[property]
        }
    }
}

Then in your controller:

TestController = function($scope, TestFactory) {
    $scope.TestClick = function () {

        TestFactory.SetName('a','test A')
        TestFactory.SetName('b','test B')

        console.log('A', TestFactory.GetName('a')); // test A
        console.log('B', TestFactory.GetName('b')); // test B

    }   
}

Upvotes: 2

Related Questions