TechQuery
TechQuery

Reputation: 253

Angular JS Factory Clarification

what is the difference between all these Factory definitions

app.factory('myFirstFactory', function () {

    var customShow = function () {
        return "My First Factory";
    }

    return customShow;

});



app.factory('mySecondFactory', function () {
    return {
        show: function () {
            return "My Second Factory";
        }
    }
});

app.factory('myThirdFactory', function () {
    function myCustomShow() { 
        return "My Third Factory";
    }
    return {
        show: myCustomShow
    }
});

Here is how its been called in the controller. What is the ideal case of defining the factory. What is the actual return type from the factory, In one defintion, it could seems like Factory and Service are look alike. Can someone please clarify

$scope.message1 = myFirstFactory();
$scope.message2 = myService.show();
$scope.message3 = mySecondFactory.show();
$scope.message4 = myThirdFactory.show();

Upvotes: 0

Views: 77

Answers (2)

LordTribual
LordTribual

Reputation: 4249

It's all about your preference how to handle the interface of the factory. Another point is best practice. The third one is suggested by John Papa in his detailed angular-styleguide even though he puts the the interface at the top and not below all functions due to readability. It's actually derived by the Revealing Module Pattern.

The first remindes me of a class definiton if there is only a single function returned by the factory. Thus it has to be invoked when you inject it into your controller as follows:

function MyController($scope, myFirstFactory)
{
    // $scope.myFirstFactory would print out "My First Factory"
    $scope.myFirstFactory = myFirstFactory();
}

This is usually used if you plan to write object-oriented AngularJS services, since factories are useful to define a classes that you can instantiate many times using the new keyword, while services always create singletons.

app.factory('MyFirstFactory', function() {
    var privateVariable = 'foo';

    // Constructor
    var MyFirstFactory = function(bar) {
        this.bar = bar;
    };

    MyFirstFactory.prototype.showCustom = function() {
        return "My Third Factory";
    };

    return MyFirstFactory;
});

You could then create many instances like so:

function MyController($scope, myFirstFactory)
{
    // $scope.myFirstFactory would print out "My First Factory"
    $scope.myFirstFactory = new MyFirstFactory();
    $scope.showCustom = myFirstFactory.showCustom();
}

The second is a variation of the third one which both return an object as @jb-nizet mentioned.

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691755

The first one returns customShow. customShowis declared as a function. So the service returned by this factory is a function. So, when you inject myFirstFactoryin a controller or another service, the injected value will be a function. BTW, you shouldn't choose xxxFactoryas the name. The component you're defining, thanks to a factory, is a service, not a factory. What is injected is the returned service, not its factory.

The second one and the thirst one both return an object:

return {
    show: ...
}

So what will be injected in both cases is an object, and not a function like in the first case.

The returned object has a single field named show, which is a function. The second one defines a named function, and assigns this named function to the showproperty of the returned object, whereas the third one directly assigns an anonymous function to the showproperty of the returned object. But the end result is the same. The only difference you'll see is when printing (for debugging) the function itself:

console.log(theService.show);

will print

function myCustomShow() { ... }

for the second one, but will print

function () { ... }

for the third one.

Upvotes: 1

Related Questions