Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: Using Shared Service(with $resource) to share data between controllers, but how to define callback functions?

Note: I also posted this question on the AngularJS mailing list here: https://groups.google.com/forum/#!topic/angular/UC8_pZsdn2U

Hi All,

I'm building my first AngularJS app and am not very familiar with Javascript to begin with so any guidance will be much appreciated :)

My App has two controllers, ClientController and CountryController. In CountryController, I'm retrieving a list of countries from a CountryService that uses the $resource object. This works fine, but I want to be able to share the list of countries with the ClientController. After some research, I read that I should use the CountryService to store the data and inject that service into both controllers.

This was the code I had before:

CountryService:

services.factory('CountryService', function($resource) {
    return $resource('http://localhost:port/restwrapper/client.json', {port: ':8080'});
});

CountryController:

//Get list of countries         
//inherently async query using deferred promise
$scope.countries = CountryService.query(function(result){       
        //preselected first entry as default
    $scope.selected.country = $scope.countries[0];  
});

And after my changes, they look like this:

CountryService:

services.factory('CountryService', function($resource) {
    var countryService = {};

    var data;
    var resource = $resource('http://localhost:port/restwrapper/country.json', {port: ':8080'});

    var countries = function() {
        data = resource.query();
        return data;
    }

    return {
        getCountries: function() {
            if(data) {
                console.log("returning cached data");
                return data;
            } else {
                console.log("getting countries from server");
                return countries(); 
            }

        }
    };
  });

CountryController:

$scope.countries = CountryService.getCountries(function(result){
        console.log("i need a callback function here...");
});

The problem is that I used to be able to use the callback function in $resource.query() to preselect a default selection, but now that I've moved the query() call to within my CountryService, I seemed to have lost what.

What's the best way to go about solving this problem?

Thanks for your help, Shaun

like image 508
shaunlim Avatar asked Oct 07 '12 19:10

shaunlim


People also ask

How can we share the data between controllers in AngularJS?

Approach: To share data between the controllers in AngularJS we have two main cases: Share data between parent and child: Here, the sharing of data can be done simply by using controller inheritance as the scope of a child controller inherits from the scope of the parent controller.

Is used to share data between controller and view in AngularJS?

14) Which of the following is used to share data between controller and view in AngularJS? Answer: B: "using services" is the correct answer.

What is callback in AngularJS?

Callback function is a function which is passed to a function as parameter and is executed when the outer function is completed. Callbacks are a feature of JavaScript not particularly angularjs. Its a way to send a function as a parameter to the callee so that the callee call that function once the task is finished.

What is the second argument in$ watch in AngularJS?

The $watch keep an eye on the variable and as the value of the variable changes the angular JS $what runs a function. This function takes two arguments one is the new value and another parameter is the old value.


2 Answers

Ok..so looks like I solved the problem by passing a callback function all the way up to the resource.query() call. Still not sure if this is the best way to do this.

For reference, this is what I did:

CountryController:

$scope.countries = CountryService.getCountries(function(){
    //preselected default
    $scope.selected.country = $scope.countries[0];  
});

CountryService:

//Country Service. Will contain all relevant rest methods here
services.factory('CountryService', function($resource) {
    var countryService = {};

    var data;
    var resource = $resource('http://localhost:port/restwrapper/country.json', {port: ':8080'});

    var countries = function(callback) {
        data = resource.query(callback);
        return data;
    }


    return {
        getCountries: function(callback) {
            if(data) {
                console.log("returning cached data");
                return data;
            } else {
                console.log("getting countries from server");
                return countries(callback); 
            }

        }
    };
  });
like image 101
shaunlim Avatar answered Sep 30 '22 22:09

shaunlim


You should take a look at the $q service, you can do:

promise.then(callback);

From 1.1.3, you can access promises with $then, for exemple resource.query().$then(callback);

like image 28
Guillaume86 Avatar answered Sep 30 '22 22:09

Guillaume86