dmudro
dmudro

Reputation: 3104

AngularJS: factory model not updated in controller

I have an AngularJS factory returning a simple model, which is consumed in a controller:

app.factory('myFactory1', function () {
    var model = {
        foo: 'original'
    };

    function changeModel () {
        model = {
            foo: 'changed'
        }
        // model.foo = 'changed'; would work! why?
    }

    // esposed API
    return {
        model: model,

        changeModel: function () {
            changeModel();
        }
    };  

});

function FooCtrl (myFactory1) {
    myFactory1.changeModel();
    this.model1 = myFactory1.model // model1 not updated
}

The issue is that the view model in the controller is not updated after chnageModel() was called. Full example in this fiddle: http://jsfiddle.net/eobq064h/1/

Upvotes: 0

Views: 71

Answers (2)

Samuel Neff
Samuel Neff

Reputation: 74909

The problem is in the factory you close over model and then you replace model with a new model. This replacement does not affect the original closure--the original model is unchanged and the closure is replaced by a reference to a new instance. Instead of replacing model you have to update the contents of model.

This is exactly why your commented out line works correctly. It updates the contents of model, not model entirely.

function FooCtrl (myFactory1) {
    myFactory1.changeModel();
    this.model1 = myFactory1.model // model1 not updated
}

app.factory('myFactory1', function () {
    var model = {
        foo: 'original'
    };

    function changeModel () {
        model.foo = 'change';
    }

    // esposed API
    return {
        model: model,

        changeModel: function () {
            changeModel();
        }
    };  

});

function FooCtrl (myFactory1) {
    myFactory1.changeModel();
    this.model1 = myFactory1.model // model1 not updated
}

Upvotes: 1

noypi
noypi

Reputation: 991

here have updated to be like what you wanted, plus adding comments and labeling your function (on which is factory and which is service) but not touching your FooCtrl. Just your factory1 and factory2

http://jsfiddle.net/eobq064h/2/

app.factory('myFactory2', function TheFactory() {
    var model = {
        foo: 'original'
    };

    // returning a new service instance
    return new TheService();
    // esposed API
    // returning a service with api and a model
    function TheService() {
        var oThis = this;

        oThis.model = model;

        // public methods
        oThis.changeModel = function () {
            changeModel();
        }

        // private methods
        function changeModel() {
            oThis.model.foo = 'changed';
        }
    };  
});

Upvotes: 0

Related Questions