javascriptangularjsangular-promiseangular-resourceangularjs-ng-resource

AngularJS wait for $resource response to set value


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:

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


Solution

  • 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;
        });
    };