Felix Gluschenkov
Felix Gluschenkov

Reputation: 55

Angular service not storing data between two controllers

I am trying to use a service to set title in controller1 and then access title in controller2.

sharedProperties.setTitle(title) works in controller1, but when I try to get the title in controller2, it gets "title" (the initial value) instead of the new value.

I've also tried storing title in an object but it didn't work.

app.service('sharedProperties', function () {
    var title = "title"

    return {
        getTitle: function () {
            return title;
        },
        setTitle: function (val) {
            title = val;
        }
    }
});

app.controller('controller1', ['$scope', 'sharedProperties', function ($scope, sharedProperties) {

    $('body').on("click", "button[name=btnListItem]", function () {
        // gets the title
        var title = $(this).text();
        // sets the title for storage in a service
        sharedProperties.setTitle(title);
    });

}]);

app.controller('controller2', ['$scope', 'sharedProperties', function ($scope, sharedProperties) {

    $scope.sharedTitle = function() { 
            return sharedProperties.getTitle(); 
    }; 

}]);

And in my view, I have {{ sharedTitle() }} which should, as I understand it, update the title text with the new title.

Also, in case this is relevant: the two controllers are linked to two different html pages.

What am I doing wrong?

EDIT Updated button listener:

$('body').on("click", "button[name=btnListItem]", function () {
    // gets the text of the button (title)
    var title = $(this).text();

    sharedTitle(title);
    alert(sharedProperties.getTitle());
    document.location.href = '/nextscreen.html';
});

$scope.sharedTitle = function (title) {
    sharedProperties.setTitle(title);
};

Upvotes: 1

Views: 500

Answers (3)

logee
logee

Reputation: 5067

You need to use the $apply so that angular can process changes made outside of the angular context (in this case changes made by jQuery).

$('body').on("click", "button[name=btnListItem]", function () {
    // gets the title
    var title = $(this).text();
    // sets the title for storage in a service
    $scope.$apply(function() {
      sharedProperties.setTitle(title);
    });

});

See plunker

That said, this is BAD PRACTICE because you're going against what angular is meant for. Check “Thinking in AngularJS” if I have a jQuery background?. There are cases when you need to use $apply like when integrating third party plugins but this is not one of those cases.

Upvotes: 0

yazaki
yazaki

Reputation: 1632

It seems to be correct in your sample code. I setup jsfiddle and it seems work correctly. Finding out a difference between my jsfiddle and your actual code would help you to find the problem you should solve.

Javascript:

angular.module('testapp', [])
.service('sharedProperties', function(){
    var title = 'title';
    return {
        getTitle: function(){
            return title;
        },
        setTitle: function(val){
            title = val;
        }
    };
})
.controller('controller1', function($scope, sharedProperties){
    $scope.change_title = function(newvalue){
        sharedProperties.setTitle(newvalue);
    };
})
.controller('controller2', function($scope, sharedProperties){
    $scope.sharedTitle = function(){
        return sharedProperties.getTitle();
    };
})

Html:

<div ng-app="testapp">
    <div ng-controller="controller1">
        <input ng-model="newvalue">
        <button ng-click="change_title(newvalue)">Change Title</button>
    </div>
    <div ng-controller="controller2">
        <span>{{sharedTitle()}}</span>
    </div>
</div>

My jsfiddle is here.

Upvotes: 1

Paresh Gami
Paresh Gami

Reputation: 4792

You have to print console.log(sharedProperties.getTitle()); Dont need return from controller.

So your code of controller2 is $scope.sharedTitle = sharedProperties.getTitle();

Upvotes: 0

Related Questions