Wait for the promise to complete before processing the result.

I have a service wrapping a third-party API that I use to retrieve data into a controller. I would like to do some processing to collapse the data before displaying it, but I cannot work out how to do it after the promise is completed. Until then, there is no data to process!

I tried several different ways, but none of them work:

angular.module('myApp').controller('myController', function ($scope, MyService) {
    $scope.getData = function () {
        MyService.getData(myParams)
            .then(function (results) {
                $scope.queryResults = results;
                // Can't do processing here, data hasn't been retrieved yet
            }, function (err) {
                $scope.alerts.push({ msg: 'Unable to get data', type: 'danger' });
            });
    }

    $scope.$watch('queryResults', function(newVals) {
        // Can't do processing here either, this only fires at
        // "$scope.queryResults = results;"
        // above where "results" is still an empty array
    });
};

And the service:

angular.module('myApp').service('MyService', ['$q', function($q) {
    return {
        getData: function (params) {
            var operation = $q.defer();
            ThirdPartyLibrary.getData(params, { callback: function(err, results) {
                if (err == null ) {
                    operation.resolve(results);
                } else {
                    operation.reject(err, results);
                }
            }});
            return operation.promise;
        }
    }
}]);

This should be pretty common, but I can't find much on Google - although I was probably looking for the wrong things!

EDIT

OK, so I reworked a lot of things, and the main problem still is that my promise chains are progressing before the data is returned earlier in the chain. Here's the new code:

angular.module('myApp').service('MyService', ['MyWrapperService', function(MyWrapperService) {
    var getDataForFilter = function(myApi, filter) {
        var processedResults = {};
        // This is the chain I'm having problems with
        return MyWrapperService.getRelevantKeys(myApi, filter).then(MyWrapperService.getDetailsForKeys).then(function(results){
            //do some processing here
            return processedResults;
        }, function(errors) {
            return errors;
        });
    };

    return {getDataForFilter: getDataForFilter};
}]);

angular.module('myApp').service('MyWrapperService', ['$q', function($q) {
    var getRelevantKeys = function(myApi, filter) {
        var operation = $q.defer();
        myApi.getKeys({'filter': filter, 'callback': function (err, results) {
            if (err == null) {
                    // This does get called correctly, but not until after the rest of the chain has been called.
                operation.resolve(myApi, results, filter);
            } else {
                operation.reject(err, results);
            }
        }
    };
    var getDetailsForKeys = function(myApi, keys, filter) {            
        var operation = $q.defer();
        var promises = [];
        var details = [];
        var errors = [];

        angular.forEach(keys, function (val) {
            // Get the data for each key. ***When this is called, 'keys' is still undefined.***
            promises.push(getDataForKey(myApi, val, filter).then(function(result){
                details.push(result);
            }, function(err, result) {
                errors.push(err);
            }));
        });

        $q.all(promises).then(function() {operation.resolve(details);}, function() {operation.reject(errors)});
        return operation.promise;
    };
    var getDataForKey = function(myApi, key, filter) {
        var operation = $q.defer();
        myApi.getDetail(key, {
            'filter': filter,
            'callback': function(err, results) {
                if (err == null) {
                    operation.resolve(myApi, results, activity);
                } else {
                    operation.reject(err, results);
                }
            }
        });
        return operation.promise;
    };

    return {
        getRelevantKeys: getRelevantKeys,
        getDetailsForKeys: getDetailsForKeys,
        getDataForKey: getDataForKey,
    };
}]);

, API , , , , , ( getDataForFilter), . , - .

( !)

+4
1

, , ! , , $q.resolve() $q.reject() , , , ( ), then() .

- , , , , , :

operation.resolve(arg1, arg2, arg3);

:

operation.resolve({'arg1': arg1, 'arg2': arg2, 'arg3':arg3});

, .

0

Source: https://habr.com/ru/post/1619471/


All Articles