1

There's quite a few topics out there covering issues with sharing data between controllers, but I havn't found any good answers for my case.

I have one controller that fetches data asynchronous using promise. The controller then makes a copy of the data to work with within that scope. I then have a second controller which I want also want to work on the same copy of data that of the first controller so they both share it.

Here's some code simplified to serve as example:

.controller('firstController', function ($scope, someService){
    var vm = this;
    someService.getData().then(function(data) {
        angular.copy(data, vm.data); //creates a copy and places it on scope
        someService.setCurrentData(vm.data)
    }
});

.controller('secondController', function ($scope, someService){
    var vm = this;
    vm.data = someService.getCurrentData(); //Triggers before the setter in firstController
});

.factory('someService', function(fetchService){
    var _currentData = {};

    var getData = function(){
        return fetchService.fetchData().then(function(data) { return data; });
    };

    var getCurrentData = function(){
        return _currentData;
    }

    var setCurrentData = function(data){
        _currentData = data;
    }
});

As the getData is async will the setCurrentData be triggered after the getCurrentData, so getCurrentData gives a different object and does not change to the correct one. I know you can solve this with broadcast and watch, but I'm trying to avoid using it if possible.

1
  • 1
    You should keep the async API for getCurrentData(), if _currentData isn't set, getCurrentData() should call getData(). Commented Jan 15, 2015 at 16:00

2 Answers 2

4

Refactor your factory to check if the _currentData variable has already been set - then you can simply use callbacks:

app.factory('someService', function(fetchService){
    var _currentData = null;

    var setCurrentData = function(data){
        _currentData = data;
    }

    var getData = function(callback) {
        if (_currentData == null) {
            fetchService.fetchData().success(function(data) { 
                setCurrentData(data);
                callback(data); 
            });
        } else {
            callback(_currentData);
        }
    };

    /*
    var getCurrentData = function(){
        return _currentData;
    }
    */
});

Now, calling your getData service will check if the data is already got and stored, if so, use that, else go get it!

someService.getData(function(data) {
    console.log(data); //yay for persistence!
})
Sign up to request clarification or add additional context in comments.

1 Comment

Nice, but what I don't like is the callback function inside the getData. Wouldn't it be better for getData to return a promise?
2

I would solve in this way:

.controller('firstController', function ($scope, $rootScope, someService){
    var vm = this;
    someService.getData().then(function(data) {
        angular.copy(data, vm.data); //creates a copy and places it on scope
        someService.setCurrentData(vm.data);
        $rootScope.$broadcast('myData:updated');
    }
});



.controller('secondController', function ($scope, $rootScope, someService){
        var vm = this;
        $rootScope.$on('myData:updated', function(event, data) {
           vm.data = someService.getCurrentData(); 
        });
});

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.