0

I have an Angular application where in I'm pulling from a model some data which is saved on the load of the app. For simplicity sake, I've explicitly defined the data which is being pulled.

The issue I have is that in one of my controllers I am running a function on load of the controller which modifies the data pulled from the model. The point is that I want that extra data for that page which is using that controller only. I don't want that data to be saved back into the model (which is what's happening).

My model:

'use strict';
(function () {
    var PotsMod = function ($log, _) {
        return {
            pots: [
                {"comp" : "comp1"},
                {"comp" : "comp2"}
            ],
            getPots: function () {
                return this.pots;
            },
        };
    };
    angular
        .module('picksApp.models')
        .factory('PotsMod', PotsMod);
})();

My controller:

(function () {
    function AdmCtrl($log, $routeParams, PotsMod) {
        var vm = this;
        vm.pots = PotsMod.getPots();
        vm.init = function() {
            // populate pot.competition
            _.forEach(vm.pots, function(pot) {
                pot.comp = "test";
            });
            console.log(PotsMod.getPots());
        }
        vm.init();
    }
    angular
        .module('picksApp.controllers')
        .controller('AdmCtrl', AdmCtrl);
})();

The final line in vm.init(), PotsMod.getPots(), returns to me the updated model, with the values of "comp" as test.

So I tried this instead - I put the debug line under vm.pots like so:

    var vm = this;
    vm.pots = PotsMod.getPots();
    console.log(vm.pots);
    vm.init = function() {....

This also returns to me the array where the object values are test...

So I tried one final thing and added an extra debug line in the vm.init() function too:

    var vm = this;
    vm.pots = PotsMod.getPots();
    console.log(vm.pots);
    vm.init = function() {
        // populate pot.competition
        _.forEach(vm.pots, function(pot) {
            console.log(pot.comp);
            pot.comp = "test";
        });
        console.log(PotsMod.getPots());
    }
    vm.init();

The result of this confuses me... The output in the console reads:

[{"comp":"test"},{"comp","test"}]
comp1
comp2
[{"comp":"test"},{"comp","test"}]

I must be missing something here because I don't understand how it can be defining a variable using a model's value, printing that variable with the updated values, then using the old values and printing them, then printing the updated values again from the model (even though nothing in this code touches the model).

Any help would be brilliant please, I see to be making a fundamental mistake somewhere. Thank you.

5
  • So if I understand correctly, you want vm.pots to be a new instance of PotsMod's pots in your controller? Have you tried vm.pots = angular.copy(PotsMod.getPots()); ? This will create a deep copy of the return value of getPots. Commented Jan 12, 2016 at 16:48
  • Hi, I would have thought it's always a copy as I'm not directly overwriting PotsMod.pots. Are you saying that by using vm.pots = PotsMod.getPots(); I've essentially created a link between vm.pots and PotsMod.pots? Commented Jan 12, 2016 at 16:50
  • Yes. You are referencing the same object. You have to create a clone of it otherwise you will be modifying the referenced object as well. Commented Jan 12, 2016 at 16:52
  • I see, I never actually knew that, I need to make some changes in a lot of places then. Thank you for the information, I'll try this now and see how it goes. I'll get back to respond on here either soon, or tomorrow morning. Commented Jan 12, 2016 at 16:54
  • see the plunk I added as an answer for an example of how this works. It might help to visualize it. Commented Jan 12, 2016 at 17:11

1 Answer 1

1

You're referencing the service's pots object in your controller, so your controller code is also modifying the service's code.

I created a Plunker to demonstrate how angular.copy() creates a deep copy of your service's 'pots', and thus your controller's model is no longer referencing the original.

In your case, all you need to change is vm.pots = angular.copy(getPots());

http://plnkr.co/edit/jg5mWIWds1KMJd51e3o5?p=preview

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

1 Comment

Thanks this looks like it's working perfectly, appreciate the help. I'm going to have to re-read up on services and models because this is a major oversight on my part

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.