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.

Gary
  • 395
  • 2
  • 7
  • 24
  • 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. – developthewebz Jan 12 '16 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? – Gary Jan 12 '16 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. – developthewebz Jan 12 '16 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. – Gary Jan 12 '16 at 16:54
  • see the plunk I added as an answer for an example of how this works. It might help to visualize it. – developthewebz Jan 12 '16 at 17:11

1 Answers1

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

developthewebz
  • 1,827
  • 3
  • 17
  • 43
  • 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 – Gary Jan 13 '16 at 09:19