Search code examples
angularjsangularjs-serviceangularjs-controllerangularjs-components

AngularJS 1.6.9 controller variable bound to service variable doesn't change


I have 2 components which are both accessing a service. One component delivers an object and the other one is supposed to display it or just receive it. The problem is that after the initialization process is finished the variable in the display component doesn't change.

I have tried using $scope , $scope.$apply(), this.$onChanges aswell as $scope.$watch to keep track of the variable, but it always stays the same.

This controller from the display component provides a text, which is from an input field, in an object.

app.controller("Test2Controller", function ($log, TestService) {

    this.click = function () {
        let that = this;
        TestService.changeText({"text": that.text});
    }
});  

That is the the service, which gets the objekt and saves it into this.currentText.

app.service("TestService", function ($log) {

    this.currentText = {};

    this.changeText = function (obj) {
        this.currentText = obj;
        $log.debug(this.currentText);
    };

    this.getCurrentText = function () {
        return this.currentText;
    };

});  

This is the controller which is supposed to then display the object, but even fails to update the this.text variable.

app.controller("TestController", function (TestService, $timeout, $log) {

    let that = this;

    this.$onInit = function () {
        this.text =  TestService.getCurrentText();
        //debugging
        this.update();
    };

    //debugging
    this.update = function() {
        $timeout(function () {
            $log.debug(that.text);
            that.update();
        }, 1000);
    }

    //debugging
    this.$onChanges = function (obj) {
        $log.debug(obj);
    }


});  

I spent quite some time searching for an answer, but most are related to directives or didn't work in my case, such as one solution to put the object into another object. I figured that I could use $broadcast and $on but I have heard to avoid using it. The angular version I am using is: 1.6.9


Solution

  • I see a problem with your approach. You're trying to share the single reference of an object. You want to share object reference once and want to reflect it wherever it has been used. But as per changeText method, you're setting up new reference to currentText service property which is wrong.

    Rather I'd suggest you just use single reference of an object throughout and it will take care of sharing object between multiple controllers.

    Service

    app.service("TestService", function ($log) {
        var currentText = {}; // private variable
        // Passing text property explicitly, and changing that property only
        this.changeText = function (text) {
            currentText.text = text; // updating property, not changing reference of an object
            $log.debug(currentText);
        };
        this.getCurrentText = function () {
            return currentText;
        };
    });
    

    Now from changeText method just pass on text that needs to be changed to, not an new object.