1

I am new to js. I have a big web app, potentially will have more than ten factories.

Here is my code. All the factory and service are in the same module

here is an example of factories

.factory('A', function(){
        return function A(){
           this.number;
           this._id= new Date().getTime();
           this.type = "A";
        };
    }).factory('B', function(){
        return function B(){
        this.type= "B";
        this.number;
        this._id= new Date().getTime();
        };
    })

And I have a service which creates new instance of factory object. the addUnit() function actually map to users click, so the type probably be A, probably be B. I know I can have functions for each of A and B, but because of the potential number of factories, i hope i could use only one creation function which takes type as a parameter and create new object according to the type.

   .service('myService', ['A','B',
    function(A, B){    
        this.addUnit = function(type) {
            console.log(typeof A);
            var myUnit = new window[type]({   //ERROR!!
                'number' : 3,
            });

            return myUnit;
        }

        addUnit("A");
}])

However, the console could print out typeof A is function, but i got an error window[type] is not a function.

SOLUTION: Thanks @Claies ' suggestion, updated my service as below and works!

    .service('myService', ['A','B',
         function(A, B){    
          var $injector = angular.injector(['moduleName','ng']);
            this.addUnit = function(type) {
                console.log(typeof A);
                var myUnitFunc = $injector.get(type);
                var myUnit = new myUnitFunc({
                  'number' : 3,
                });

                return myUnit;
            }

           addUnit("A");
    }])
14
  • 2
    your question isn't really clear. typeOf A and typeOf "A" aren't the same. one would be a function, the other a string. Commented Sep 14, 2015 at 14:21
  • @Claies sorry about the typo. updated Commented Sep 14, 2015 at 14:22
  • what is window? how is it supposed to relate to these factories? Commented Sep 14, 2015 at 14:29
  • @Claies Well... that is my question. I console typeof A just to make sure the dependency is correct. window["A"] is supposed to convert a string to a function, but it doesn't work for me..... Commented Sep 14, 2015 at 14:29
  • @Ting: In angularjs you can obtain a provider (service/factory) through dependency injection. If addUnit is defined inside a controller/service, you can inject A into that controller/service and you will be able to call functions on A. Can you provide the whole source/scope where addUnit is defined so we know what you want to achieve? Commented Sep 14, 2015 at 14:30

3 Answers 3

1

You can use the $injector if you want to instantiate providers by their name (providing their name as a string).

.service('myService', ['$injector', function($injector) {

  this.addUnit = function(type) {

    var instance;

    if ($injector.has(type))
    {
      var typeConstructor = $injector.get(type);
      instance = new typeConstructor();
      instance.number = 3;
    }

    return instance;
  }

}])

Here is a working sample: http://plnkr.co/edit/t4ILB4CV11Lni8pLGQ9j

Sign up to request clarification or add additional context in comments.

2 Comments

Though I figured out solution by @Claies suggestion, I'll give you credit. Thanks for your working example!
Good. This will serve as an answer for others as well.
0

Use service not factory.

.service('A', function(){

And the later code is wrong. I even can't guess what were you going to do. There is only one instans of service/factory.

5 Comments

it still gave me error : 'window[type] is not a function'
@Ting, anyway you are doing something awful.
why? do you have any suggestions?
@Ting, see my other answer.
I think you just need a JS Object.. function(n){this.name=n}... I think using a factory is overkill/wrong
0
.constant('A', function A(number) {
  this._id = Date.now();
  this.type = "A";
  this.number = number;
})
.constant('B', function B(number) {
  this._id = Date.now();
  this.type = "B";
  this.number = "number";
})

.service('myService', ['A', 'B', function (A, B) {
  var constructors = {A:A, B:B};

  this.addUnit = function (type) {
    var C = constructors[type];
    return C && new C(3);
  };
}]);

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.