简体   繁体   中英

How to make multiple http requests in my case

I'm trying to chain a promise with Angular $resource.

I have the following factory:

angular.module('myApp').factory('Product', ['$resource', function ($resource) {
    return $resource(
        '/api/product/:name',
        { name: '@name' },
        { 'getSub': {
                url: '/api/product/getSub/:name',
                method: 'GET'}
         }
    );
}]);

I make multiple queries using my Product factory as such:

Product.query({'name': name}, function(product) {
     Product.getSub({'name': product.name}, function(subItem) {
         Product.getSub({'name':subItem.name}, function(childItem) {
             //do stuff with child item
         })
     })
})

Is there a better way to do this? I feel like nesting all these calls is not a best practice.

You can chain the promises together!

Product.query({'name': name}).$promise
.then(function(product){
  return Product.getSub({'name': product.name}).$promise;
})
.then(function(subItem){
  return Product.getSub({'name': subItem.name}).$promise;
})
.then(function(item){
  // etc
})

you can use waterfall of async library or implement it yourself.
here's sample code for your case.

async.waterfall([
    function(callback) {
        Product.query({'name': name}, function(product) {
            callback(null, product);
        })
    },
    function(product, callback) {
        Product.getSub({'name': product.name}, function(subItem) {
            callback(null, product, subItem);
        })
    },
    function(product, subItem, callback) {
        Product.getSub({'name':subItem.name}, function(childItem) {
            var result = {};
            result.childItem = childItem;
            result.subItem = subItem;
            result.product = product;

            callback(null, result);
        })
    }
], function (err, result) {
    //do stuff with result
});

A useful solution maybe use $q library

https://docs.angularjs.org/api/ng/service/ $q

You can use the method $q.all() to send a lot of request and manage only one callback then() or make $q.defer() and resolve por reject your oun promises.

I currently answer this question from a mobile device and i can't make an example. Sorry about that. If when I get home that mistake trains still try to help

If you want the requests to be done one after another (like you have in your example) you could do a recursive function like this:

in this example i want to upload a couple of images (calling a http route):

$scope.uploadImageLayout = function (currentIndex, numberOfItems) {
        if (currentIndex === numberOfItems) {
            // in here you could do some last code after everything is done
        } else {
            Upload.upload({
                url: 'localhost:3000/ficheiros',
                file: $scope.imagesToUpload[$scope.auxIndex].file
            }).success(function (data, status, headers, config) {
                if ($scope.auxIndex < numberOfItems) {
                    $scope.uploadImageLayout(currentIndex + 1, numberOfItems);
                }
            });
        }
    };

and the first time you call just do this:

$scope.uploadImageLayout(0, $scope.imagesToUpload.length);

in you case its the same but instead of the Upload.upload request you should have your request and catch the callback function(s).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM