cjds
cjds

Reputation: 8426

How to chain Angular.JS promises in a loop

I need to design a function in javascript that makes requests to POST multiple items to the database. I then have to take all the data that has been returned and run another $http query to the database.

This is my code as it stands

var current_request=null;
var workorders=[];
$scope.submit_work_order=function(){
    for(var i=0;i<$scope.parent_jobs.length;i++){
         addPartAndWorkOrder(equipment_id,part_number,work_order,_id);  
    }

    if(current_request!=null){
        current_request.then(function(){
                    if(workorders.length>0){
                        $http({
                            url:'/api/salesorders', 
                            method: "POST",
                            data: {'workorders':workorders}
                        })
                    }
        });
}

function addPartAndWorkOrder(equipment_id,part_serial_number,work_order_id, job_id){
    //part_serial_number
        var info;

        info=$http({url:'/api/parts', 
                    method: "POST",
                    data: {'equipment':equipment_id});

        if(current_request==null){
            current_request=info;
        }
        else{
            current_request.then(function(){
                return info
                });
            });
        }
        current_request.then(function(data){
            return $http({
                url:'/api/workorders', 
                method: "POST",
                data: {workorder_id:work_order_id, part:data._id,job:job_id}
            }).then(function(data){
                workorders.push(data._id);
            });
        })

}

What I need is to populate the array workorders by running the HTTP requests in the code.

Then I need to run the final run another request to the endpoint api/salesorders/ with the data from the array

TL;DR

This is the way the endpoints should run

parts->workorders->parts->workorders->salesorder

This is the way they do run

parts->salesorder->workorders->parts->workorders

I tried to keep adding to the .then but as it currently stands its still failing

Upvotes: 0

Views: 485

Answers (1)

New Dev
New Dev

Reputation: 49590

Break down your calls into dependency tree. It seems that your call pattern must by like so:

parts(1) --> workorders(data1) --> _id1
                                        \
parts(2) --> workorders(data2) --> _id2--> salesorder([_id1, id2, _id3])
                                        /
parts(3) --> workorders(data3) --> _id3

So, individually, parts-->workorder must be done sequentially, but all of them can be done in parallel to each other.

Here's how this can be done (I'm omitting specific API calls and parameters for brevity):

function submitWorkOrder(){
  var parent_jobs = [{}, {}, ]; // this is your array of jobs (however you get it)

  var partsAndOrdersPromises = [];

  parent_jobs.forEach(
    function(job){
       var promise = postPart(job).then(postWorkOrder);
       partsAndOrdersPromises.push(promise);
    });

  var allPartsAndWorkordersPromise = $q.all(partsAndOrdersPromises);

  return allPartsAndWorkordersPromise.then(postSalesOrder);
}

The postSalesOrder will look like so:

function postSalesOrder(workorders){
   // workorders is an array of results of each workorder call

   return $http.post("/api/salesorder", ...);
}

OFF-TOPIC: If you have control over your server API, you should consider creating a single API and post all of the info to create parts, workorders, and salesorder at the end as a transaction. It's not a good idea to have an API call for each, and ofcourse, it does not preserve transactional integrity (e.g. /api/salesorder might fail, but you have already submitted the previous orders)

Upvotes: 1

Related Questions