5

I'm trying to sent an array filled with objects from controller 1 to controller 2. But all I get in controller 2 is an empty array. The only way I get a filled one is when I create a static array in my service.

My service

app.service('myData', function () {
this.myData = [];

this.addData = function(data) {
    this.myData.push(data);
}
this.getData = function() {
    return this.myData;
}});

controller 1 which sets the data

app.controller('controller1',['$scope', 'myData', function($scope, myData) {
    $scope.addData = function(index, name) {
        myData.addData({index: index, name: name});
    }}]);

Controller 2 looks like this

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

$scope.myData = myData.getData();
$scope.$watch('myData.getData()', function(data){
    console.log(data);
});
console.log($scope.myData);}]);

When I was searching for an answer I found alot of questions almost similar to mine. The only difference was that I fill my service from my controller instead of creating a static service.

Both my console.logs return an empty array. Why is this?

2
  • you need to use the root scope or one of the communicartion mechanism like the broadcast or events Commented Sep 18, 2015 at 12:36
  • your watch seems a little strange to me. try this function(){ return myData.getData() } instead of data.getData() Commented Sep 18, 2015 at 12:43

4 Answers 4

1

Your $watch expression should be a function (see the docs for $watch). Giving $watch a string tells Angular to inspect a property on the $scope. As well as this, you have mistakenly referenced your myData service as 'data' in the string 'data.getData()'.

1) Watch the result of myData#getData:

$scope.$watch(function () {
    return myData.getData();
}, function (data) {
    console.log(data);
});

2) Watch the reference to the myData service's internal array on $scope:

$scope.myData = myData.getData();
$scope.$watch('myData', function (data) {
    console.log(data);
});
Sign up to request clarification or add additional context in comments.

Comments

0

It should work if you call the addData from the first controller for example:

JSFiddle

.controller('tourCtrl', ['$scope', 'myData', function ($scope, myData) {
    $scope.addData = function (index, name) {
        myData.addData({
            index: index,
            name: name
        });
    }
    $scope.addData('hello', 'world');
}])
.controller('controller2', ['$scope', 'myData', function ($scope, myData) {

    $scope.myData = myData.getData();
    $scope.$watch('myData', function (data) {
        console.log(data);
    });
    console.log($scope.myData);
}]);

Comments

0

i would suggest that you use something like pubsub mechanism. you can't know when will data appear. and watching a function is an expensive operation. You can build a PubSub mechanism on your service.

A controller could register for an event and another could publish that event. so with minimum resources you could achieve what you want.

here is a sample

app.factory('pubSubService', [function() {
var pubSubAPI = {};
var hooks = [];

pubSubAPI.publishEvent = function(message) {
    for (var i = 0; i < hooks.length; i++) {
        hooks[i](message);
    }
};

pubSubAPI.subscribeEvent = function(eventFunction) {

    hooks.push(eventFunction);
};

return pubSubAPI;
}]);

2 Comments

yes but this type of functionality on angularjs is for scopes. unless you want to use rootScope - which i am always trying to avoid. you cant use angular functionality on this issue
0

Another Approach would be to use the Observer Pattern, saves having to use the $watchat all:

app.service('myData', function () {
    this.myData = [];
    var observers = [];
    var self = this;

    this.addObserver = function (callback) {
        observers.push(callback);
    };

    var notifyObservers = function () {
        angular.forEach(observers, function (callback) {
            callback(self.myData);
        });
    };


    this.addData = function (data) {
        this.myData.push(data);
        notifyObservers();

    }
});


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

    myData.registerObserverCallback(function (data) {
        $scope.myData = data;
        console.log(data);
    });
}]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.