Giuseppe Terribilio Giuseppe Terribilio - 1 year ago 45
Javascript Question

Make a factory not Singleton in angularJS

UPDATE:

Thanks for your reply!

I've rewritten my code:

(function () {
'use strict';
angular
.module('Services', []).factory('services', ['$http', function($http,services) {
function services($http) {

var serviceProvider = function () {
this.data = [];
this.errors = [];
}
var model = {
getInstance:function(){ return new serviceProvider(); }
}
serviceProvider.prototype.init = function(){//put some init stuff here
}
serviceProvider.prototype.getFromRESTServer = function(msg,callback){
return $http.jsonp("http://xxxxxxx/JSONEngine.php?callback=JSON_CALLBACK&action="+callback+"&"+msg);
}
return model;
}
}])
})();


And my controller is defined as:

var uniqueModelInstance = services.getInstance();
uniqueModelInstance.init();
uniqueModelInstance.getFromRESTServer("username="+$scope.username+"&password="+$scope.password,"register").success(function (data) {...}


Are they correct? Now I obtain "Cannot read property 'getInstance' of undefined".

Any suggestion?

Thanks in advance.
Giuseppe

I have an angular factory defined in this way:

services.factory('services', ['$http', function($http) {
var service = {};
return {
getFromRESTServer: function (msg,callback){
return $http.jsonp("http://myUrl/JSONEngine.php?callback=JSON_CALLBACK&action="+callback+"&"+msg);
}
}
}]);


and a controller with doLogin function:

home.controller('registrazioneTraduttoreCtrl', ['$scope', '$rootScope', '$window', 'services', '$location', 'customFactory',
function ($scope, $rootScope, $window, services, $location, customFactory) {

$scope.doLogin= function(username, password) {
services.getFromRESTServer("username="+username+"&password="+password,"login").
success(function (data) {
if(data.jsonError != null || data.errCode != null)
{
alert (data.errMsg);
}
else {
// DO STUFF...
}).error(function(data, status) {
console.error('Repos error', status, data);
})

.finally(function() {
console.log("finally finished repos");
});
}


}]);

The getFromRESTServer can be also executed by another function in another controller (there are 2 different Registration form in my html page and then they call doLogin function).

When I debug my application, the debugger skip from:
services.getFromRESTServer("username="+username+"&password="+password,"login") line (in doLogin function) to the end of getFromRESTServer funcion without going in and then re-execute the doLogin function with username and password NULL and now it enter in the core of getFromRESTServer function.

Any ideas?

Thanks in advance.
Giuseppe

lin lin
Answer Source

You can do this by returning a new instance of any factory which is called. Look at this Plunker or try the following codes:

/**
 * Non singleton factory example
 *
 * @name        non-singleton-example
 * @author      Nils Gajsek <[email protected]>
 */
(function () {

    //use strict -> ECMAScript5 error reporting
    'use strict';


    // ################################################ angularJS Module define // ####################################

    /**
     * DB service, part of app module
     */
    angular
        .module('app.model', [])  // [-_-]
        .factory('model', ['$http', model]);


    /**
     * Model factory wrapper
     *
     * @param {object} $http
     *
     * @returns self
     */
    function model($http) {


        // ################################################## Vars // ##############################################

        var serviceProvider = function(){

            /**
             * Data store
             * @type {Array}
             */
            this.data = [];


            /**
             * Error store
             * @type {Array}
             */
            this.errors = [];
        }


        // ############################################### Functions // ############################################

        /**
         * Model instance provider handler
         * This object is returned on the end of this object
         */
        var model = {
            getInstance:function(){ return new serviceProvider(); }
        }


        /**
         * Model init function, provides
         */
        serviceProvider.prototype.init = function(){

            //put some init stuff here
        }


        /**
         * Example function
         *
         * @returns {{this}}
         */
        serviceProvider.prototype.someFunction = function(){
            //do some stuff with model
        }


        //return model -> non-singleton model instance object
        return model;
    }
})();

This is how you receive it as unique instance.

 var uniqueModelInstance = model.getInstance();
 uniqueModelInstance.init();

Or better (but you need to return the instance itself by calling init() the function)

var uniqueModelInstance = model.getInstance().init();
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download