badigard
badigard

Reputation: 850

Use Javascript Object to Angular Service

I am trying to add functions to a JS Object which will be used as a singleton service.

angular
        .module('app.steps')
        .factory('createStepsService', createStepsService);

    createStepsService.$inject = [];

    /* @ngInject */
    function createStepsService() {
        var steps;

        var service = {
            newSteps: function (current_step, total_steps) {
                if (!steps) {                   
                    return new Steps(current_step, total_steps);
                }
            }            
        };
        return service;

        function Steps(current_step, total_steps) {
            this.c_step = current_step;
            this.t_step = total_steps;            
        }

        Steps.prototype = {
            addSteps: function (num) {
                this.c_step += num;
            },
            setLastStep: function () {
                this.lastStep = this.c_step = this.t_step;
            }
        };        
    }

When I run this line from the controller, I am not able to access addSteps / setLastStep methods.

vm.createStepsService = createStepsService.newSteps(1, 3);

Why I don't see these methods? Were they created?

Thanks.

Upvotes: 0

Views: 85

Answers (3)

floribon
floribon

Reputation: 19193

Your problem is that you are creating Steps.prototype after a return statement, so it will never be read.

Upvotes: 1

kbnawale
kbnawale

Reputation: 11

In AngularJS, services are singletons objects that are instantiated only once per app.

And the factory() method is a quick way to create and configure a service. It provides the function's return value i.e. Need to create an object, add properties to it, then it will return that same object.

For ex:

angular
.module('myApp',[])
.factory("createStepService", function(){
    var stepServiceObj = {};
    var c_step = 0;
    var t_steps = 0;
    var last_step = 0;

    stepServiceObj.setCurrentStep = function(current_step){
        c_step = current_step;
        console.log('c_step1: ',c_step);
    };
    stepServiceObj.getCurrentStep = function(){
        return c_step;
    };

    stepServiceObj.setTotalStep = function(total_steps){
        t_steps = total_steps;
    };
    stepServiceObj.getTotalStep = function(){
        return t_steps;
    };

    stepServiceObj.setLastStep = function(){
        last_step = c_step = t_step;
    };
    stepServiceObj.getLastStep = function(){
        return last_step;
    };

    stepServiceObj.addSteps = function(num){
        return c_step += num;
    };

    return stepServiceObj;
});

Upvotes: 0

Matt Lishman
Matt Lishman

Reputation: 1817

Your steps.prototype code is never ran.

This is because it appears after the return.

Change the order of your code to this:

/* @ngInject */
function createStepsService() {
    var steps;

    function Steps(current_step, total_steps) {
        this.c_step = current_step;
        this.t_step = total_steps;            
    }

    Steps.prototype = {
        addSteps: function (num) {
            this.c_step += num;
        },
        setLastStep: function () {
            this.lastStep = this.c_step = this.t_step;
        }
    };

    var service = {
        newSteps: function (current_step, total_steps) {
            if (!steps) {                   
                return new Steps(current_step, total_steps);
            }
        }            
    };       

    return service; 
}

The reason that you can have a function declared before a return is because of JavaScript variable and function hoisting.

Upvotes: 1

Related Questions