1

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);
};

3 Answers3

1

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.

yazaki
  • 1,724
  • 1
  • 13
  • 17
  • hmm... My title is coming from a button: `list.append('');`. I added ng-click and call the shared_title function in my controller. It still doesn't seem to work. – Felix Gluschenkov Sep 03 '15 at 02:05
  • Can my transfer to a different page (see edit: `document.location.href = '/nextscreen.html';`) affect what is stored in the service? This next page links with controller2. – Felix Gluschenkov Sep 03 '15 at 02:21
  • I got it. Your way to move to next page, `document.location.href`, definitely init the state of everything in angularjs including `sharedProperties` service. You should use $routeProvider and $location service instead of document object. – yazaki Sep 03 '15 at 04:58
  • Thanks, using $routeProvider and $location works! :) – Felix Gluschenkov Sep 03 '15 at 17:35
  • I'm grad to hear it ! – yazaki Sep 04 '15 at 00:23
0

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

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

Paresh Gami
  • 4,777
  • 5
  • 23
  • 41
0

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.

Community
  • 1
  • 1
logee
  • 5,017
  • 1
  • 26
  • 34