1

Here is my problem:

I have a service created with $resource and a controller; the controller calls the service, and I try to set a value after the response (actually the error) was received. The problem is: I'm trying to set that value outside of the callback. Here is the service:

app.factory("DataService", function ($resource, ENV) {
    return $resource(ENV.apiEndpoint + "/endpoint/:id", {id:'@id'}, {
        update: { method: 'PUT' }
    });
});

It's a simple service that retrieves data from backend through a REST endpoint.

Here is the controller:

app.controller("DataController", function (DataService){
    var ctrl = this;
    ctrl.initialData = undefined;
    ctrl.data = undefined;

    ctrl.initData = function () {
        ctrl.getData();
        ctrl.data = ctrl.initialData;
    };

    ctrl.getData = function () {
        DataService.get({},
            function (response) {
                ctrl.initialData = response.content;
        }, function (error) {
                ctrl.initialData = { data1: "A" };
        });
    };
});

The Angular $resource Doc says to call the get() method this way:

The action methods on the class object or instance object can be invoked with the following parameters:

HTTP GET "class" actions: Resource.action([parameters], [success], [error])

Since my backend is not yet implemented, when debugging, I'm correctly going through the error callback function. But I can see that my data variable is still undefined.

My problem is that I'm still not really used to promises. I understand that the response from the DataService is asynchronous. So I tried to set the data in a few different ways without success. I tried:

  • To replace initData method with:

    ctrl.initData = function () {
        ctrl.getData().then(function () {
            ctrl.data = ctrl.initialData;
        }).catch(function () {
            ctrl.data = ctrl.initialData;
        });
    };
    

    But I never enter the 'catch' condition;

  • To use the $q service:

    ctrl.initData = function () {
        $q.all([ctrl.getData()]).then(function () {
            ctrl.data = ctrl.initialData;
        });
    };
    
  • To use the $q.when to create a promise from the variable ctrl.data:

    ctrl.billingInfo = $q.when(/*???*/);
    
  • Other variants of those..

I could make it work by setting the data directly in the callback functions but then it means I reset the data every time I call the getData() method and that is something I want to avoid for best practices purpose:

ctrl.getData = function () {
    DataService.get({},
        function (response) {
            ctrl.initialData = response.content;
            ctrl.data = ctrl.initialData;
    }, function (error) {
            ctrl.initialData = { data1: "A" };
            ctrl.data = ctrl.initialData;
    });
};

Is there a way to wait that the ctrl.initialData has been set before setting ctrl.data?

Any little help is greatly appreciated

LeMiniMoine
  • 13
  • 1
  • 3
  • 1
    your `getData` now return nothing, so you can use it with `$q` and etc, also resources in angular have property `$promise` that you can use – Grundy Oct 09 '15 at 17:00
  • you need to pass an argument such as res or data though your promises - that represents the return value of the previous statement – Jonah Williams Oct 09 '15 at 17:02

1 Answers1

2

You can a bit fix you getData function to return promise

ctrl.getData = function() {
    return DataService.get({}).$promise.then(
        function(response) {
            return ctrl.initialData = response.content;
        },
        function(error) {
          return ctrl.initialData = { data1: "A" };
        });
};

and then you can use it with then like

ctrl.initData = function () {
    ctrl.getData().then(function(initialData){
        //success callback
        ctrl.data = initialData;
    },function(initialData){
        //error callback
        ctrl.data = initialData;
    });
};
Grundy
  • 13,356
  • 3
  • 35
  • 55