0

I have two controllers on a parallel scope level I need to pass data between:

function TableRowCtrl($scope, $http, sharedProperties) {
  console.log(sharedProperties.getProperty());
  $scope.items = sharedProperties.getProperty();
}

and

function SideNavCtrl($scope, $http, sharedProperties) {
  $scope.customers = undefined;
  var temp = "cats";

  $http.get('data/customers.json').success(function(data) {
    $scope.customers = data;
    temp = "dogs";
    sharedProperties.setProperty(temp)
  });

  sharedProperties.setProperty(temp);
  console.log(sharedProperties.getProperty());
}

I am trying to use a service to do this (via examples I have seen) :

angular.module('myApp', []).service('sharedProperties', function() {
var property = "Cats";
return {
    getProperty: function() {
        return property;
    },
    setProperty: function(value) {
        property = value;
    }
};
});

However - when I try and set the data in the SideNavCtrl http success function, it does not bubble out - the service still returns 'cats' as its value. From what I have read, services are supposed to be global, and setting data in them should be permanent (as is its purpose). What am I doing wrong, and how can I get data between these two controllers on the same scope?

2 Answers 2

4

The problem is your TableRowCtrl saves the result of a function in its scope variable. When the service itself changes, the value in the scope does not because at that point, it's a simple property. You can either expose your service directly in the scope or wrap $scope.items in a function instead:

function TableRowCtrl($scope, $http, sharedProperties) {
    $scope.items = function() { return sharedProperties.getProperty(); };
}

// And in your view
{{ items() }}

Or

function TableRowCtrl($scope, $http, sharedProperties) {
    $scope.shared = sharedProperties;
}

// And in your view
{{ shared.getProperties() }}

Edit: Simple plunkr here

Edit #2:

If the problem is a binding that isn't updated because of an asynchronous process, you can use $scope.$apply:

$http.get('data/customers.json').success(function(data) {
  $scope.customers = data;
  temp = "dogs";
  sharedProperties.setProperty(temp)

  if(!$scope.$$phase)
    $scope.$apply();
});

Edit 3:

I've recreated your $http.get and updated the plunkr and it works. Based on what you are showing in your questions, it should work using function instead of regular properties.

Sign up to request clarification or add additional context in comments.

9 Comments

Maybe I am missing something - after wrapping it in a function, I am still at the same error - the value being set by shareProperties in the http success function is not sticking. After trying these solution, I am still cannot get that data out and sticking to the service variable. It still looks as though the original value is staying, not the one being put by the setter.
@CharlesLillo I'll reproduce in a JS Fiddle in a bit
The example helps, but still doesn't address my problem I'm afraid -if you wrap your setter in an HTTP success function, the value 'Dogs' does not stay, and will remain 'Cats'. My issue is primarily concerned with being able to set and pass data in an HTTP success function.
See my second edit. When you run think asynchronously, you might sometimes need to manually apply the changes to the scope. Even though the $http and $timeout services are supposed to do that for you (I think).
Even if forced to run synchronously, I'm still having trouble (even with applying the changes to scope). I can set my $scope.customers and have those changes remain - but sharedProperties.setProperty does not last when inside that http function. If outside, its fine, but I need to use the data being returned by the http service and pass it to another controller.
|
0

@SimomBelanger already identified the problem. I suggest using objects rather than primitives, then you don't need to call functions in your view:

<div ng-controller="TableRowCtrl">items={{items.property}}</div>
<div ng-controller="SideNavCtrl">customers={{customers}}</div>

app.service('sharedProperties', function () {
    var obj = {
        property: "Cats"
    };
    return {
        getObj: function () {
            return obj;
        },
        setObjProperty: function (value) {
            obj.property = value;
        }
    };
});

function SideNavCtrl($scope, $timeout, sharedProperties) {
    $scope.customers = undefined;
    var temp = "cats";
    $timeout(function () {
        $scope.customers = 'some data';
        temp = "dogs";
        sharedProperties.setObjProperty(temp);
    }, 2000);
    sharedProperties.setObjProperty(temp);
}

function TableRowCtrl($scope, $http, sharedProperties) {
    $scope.items = sharedProperties.getObj();
}

fiddle

In the fiddle I use $timeout to simulate an $http response.

Because getObj() returns a (reference to an) object, updates to that object are automatically picked up by the view.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.