ilovelamp
ilovelamp

Reputation: 777

AngularJS: Modifying Service within Service doesn't update Controller

I have my model in a Service, all my model is in an object, I would like to be able to reset my model by just reassign my model to an empty object, but it doesn't seem to work, but if I delete a property directly it does.

How could I reset my model without having to delete every property, refresh the page or doing big changes?

(function () {
    var myApp = angular.module('myApp', []);
    myApp.controller('MyController', function (MyService) {
        var _this = this;
        _this.model = MyService.model;
        _this.myService = MyService;

        _this.deleteInService = function () {
            MyService.functions.resetModel();
        };
    });
    myApp.service('MyService', function () {
        var obj = {};
        obj.model = {x: 1};

        obj.functions = {};
        obj.functions.resetModel = function () {

            //delete obj.model.x; //THIS WORKS!

            obj.model = {x: 1}; //BUT THIS DOESN'T :(

        };
        return obj;
    });
})();
<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
        <script src="changingModelInService.js"></script>
    </head>
    <body ng-app="myApp" ng-controller="MyController as myCtrl">
        {{myCtrl.model.x}}<div><input ng-model="myCtrl.model.x"/></div>
        <button ng-click="myCtrl.deleteInService()">Delete X in service</button>
    </body>
</html>

Thank you.

Edit: doing _this.model = MyService.model it's not possible because I share my Service with many controllers

Upvotes: 0

Views: 80

Answers (2)

Jhey
Jhey

Reputation: 1377

I think one solution to your problem would be to create a default model variable like a master copy and use angular.copy with two parameters resetting the model to a master version when invoking that method.

See the angular.copy documentation here. You'll notice the live demo actually shows a reset functionality.

I've updated the live demo plunker to show the behaviour I think you desire http://plnkr.co/edit/BJ....

Hope that helps!

UPDATE::

A possible implementation although will require testing would be as follows;

myApp.service('MyService', function () {
    var masterModel = {x: 1};
    var obj = {
      model: {x: 1},
      functions: {
        resetModel: function() {
          angular.copy(masterModel, obj.model);
        }
      }
    };
    return obj;
});

Upvotes: 1

logee
logee

Reputation: 5067

Other than angular.copy, another solution is just to not use _this.model and use _this.myService.model instead or to change your deleteInService function to

    _this.deleteInService = function () {
        MyService.functions.resetModel();
        _this.model = MyService.model;
    };

The reason you're getting this problem is because you're doing something like this:

service.model = foo;
controller.model = service.model; // implies controller.model = foo;
service.reset(); // => service.model = bar;
// But notice that controller.model still points to the old object foo

Run the code snippet below to see what I mean.

(function () {
    var myApp = angular.module('myApp', []);
    myApp.controller('MyController', function (MyService) {
        var _this = this;
        _this.model = MyService.model;
        _this.serviceModel = MyService.model;
        _this.myService = MyService;

        _this.deleteInService = function () {
            MyService.functions.resetModel();
            _this.serviceModel = MyService.model;
        };
    });
    myApp.service('MyService', function () {
        var obj = {};
        obj.model = {x: 1};

        obj.functions = {};
        obj.functions.resetModel = function () {

            //delete obj.model.x; //THIS WORKS!

            obj.model = {x: 1}; //BUT THIS DOESN'T :(

        };
        return obj;
    });
})();
<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
        <script src="changingModelInService.js"></script>
    </head>
    <body ng-app="myApp" ng-controller="MyController as myCtrl">
        <pre>myCtrl.model = {{myCtrl.model}}</pre>
        <pre>myCtrl.serviceModel  = {{myCtrl.serviceModel }}</pre>
        <pre>myCtrl.myService.model = {{myCtrl.myService.model}}</pre>
<div><input ng-model="myCtrl.model.x"/></div>
        <button ng-click="myCtrl.deleteInService()">Delete X in service</button>
    </body>
</html>

Upvotes: 1

Related Questions