Search code examples
javascriptphpangularjspromisenormalize

Calling simultaneous $http services from controller in angularJs?


I am calling many services from a controller in angularJs, Some of my code depends with other service result. Sometimes it works well and but sometimes I am getting undefined error because service execution is not completed.

If I am waiting for completion of service execution(nested code,ie one service inside another service success function etc),which means the nested $http request only start once after parent completed,It will effect performance. HOw can I solve this situation?

Sample code,

              //init client list
            clientService.list().success(function (data, status) {
                $scope.clients = data.data;
                console.log('clients retrieved');

                //sales person
                settingService.getSalesPerson().success(function (data, status) {
                    $scope.sales_persons = data;
                    console.log('sales persons retrieved');

                    //init item list
                    itemService.list().success(function (data, status) {
                        $scope.items = data.data;
                        console.log('items retrieved');

                        //quotation settings
                        settingService.getQuotationSettings().success(function (data, status) {
                            var qty = data[0];
                            $scope.quotation.note = data[0].note;
                            $scope.quotation.terms_and_condition = data[0].terms_and_condition;
                            console.log('settings retrieved');

                            //when change client,updating the address
                            var watchClientModel = function () {
                                $scope.$watch('selectedClient', function () {
                                    $scope.quotation.client_id = $scope.selectedClient.id;
                                    $scope.quotation.billing_street = $scope.selectedClient.address_info.billing_street;
                                    $scope.quotation.billing_city = $scope.selectedClient.address_info.billing_city;
                                    $scope.quotation.billing_pobox = $scope.selectedClient.address_info.billing_pobox;
                                    $scope.quotation.billing_country = $scope.selectedClient.address_info.billing_country;
                                    $scope.quotation.shipping_street = $scope.selectedClient.address_info.shipping_street;
                                    $scope.quotation.shipping_city = $scope.selectedClient.address_info.shipping_city;
                                    $scope.quotation.shipping_pobox = $scope.selectedClient.address_info.shipping_pobox;
                                    $scope.quotation.shipping_country = $scope.selectedClient.address_info.shipping_country;
                                });
                            };
                            var watchSalesPersonModel = function () {
                                $scope.$watch('selectedPerson', function () {
                                    $scope.quotation.sales_person_id = $scope.selectedPerson.id;
                                    console.log('Sales person updated');
                                });
                            };
                            //when udpate
                            if ($scope.isUpdate) {
                                //Create Quotation
                                $scope.pageTitle = "Edit Quotation";
                                $scope.pageTitleIcon = "fa fa-pencil";
                                //init quotaion details
                                quotationService.get($routeParams.quotationId).success(function (data, status) {
                                    $scope.quotation = data;
                                    //get clients
                                    $scope.selectedClient = _.findWhere($scope.clients, {id: $scope.quotation.client_id});
                                    console.log('Client preselected');
                                    //get sales person
                                    $scope.selectedPerson = _.findWhere($scope.sales_persons, {id: $scope.quotation.sales_person_id});
                                    console.log('Sales  person preselected');
                                });
                            } else {
                                //when insert
                                $scope.selectedClient = $scope.clients[0];
                                $scope.selectedPerson = $scope.sales_persons[0];
                                $scope.quotation.items.push({
                                    'item': null,
                                    'quantity': 0.00,
                                    'rate': 0.00
                                });
                                if (qty.auto_generate) {
                                    $scope.quotation.quotation_number = qty.prefix_string + 1000 + Math.floor((Math.random() * 100000) + 1);
                                }
                            }
                            watchClientModel()
                            watchSalesPersonModel();
                        });
                    });
                });
            });

Here I put all service call as nested ladder.it is working fine but effecting performance.

If I bring back all service call outside,Getting error is $scope.selectedClient is undefined


Solution

  • If you have queries that are not interdependent, you can perform them separately from each other, and then wait on the results:

    //init client list
    var clients = clientService.list().success(function (data, status) {
        $scope.clients = data.data;
        console.log('clients retrieved');
    });
    
    //sales person
    var sales = settingService.getSalesPerson().success(function (data, status) {
        $scope.sales_persons = data;
        console.log('sales persons retrieved');
    });
    
    //init item list
    var items = itemService.list().success(function (data, status) {
        $scope.items = data.data;
        console.log('items retrieved');
    });
    
    //quotation settings
    var quotes = settingService.getQuotationSettings().success(function (data, status) {
        $scope.qty = data[0];
        $scope.quotation.note = data[0].note;
        $scope.quotation.terms_and_condition = data[0].terms_and_condition;
        console.log('settings retrieved');
    });
    
    //when change client,updating the address
    $scope.$watch('selectedClient', function () {
         var selectedClient = $scope.selectedClient,
             address_info = selectedClient.address_info,
             quotation = $scope.quotation;
    
         quotation.client_id = selectedClient.id;
         quotation.billing_street = address_info.billing_street;
         quotation.billing_city = address_info.billing_city;
         quotation.billing_pobox = address_info.billing_pobox;
         quotation.billing_country = address_info.billing_country;
         quotation.shipping_street = address_info.shipping_street;
         quotation.shipping_city = address_info.shipping_city;
         quotation.shipping_pobox = address_info.shipping_pobox;
         quotation.shipping_country = address_info.shipping_country;
    });
    
    $scope.$watch('selectedPerson', function () {
        $scope.quotation.sales_person_id = $scope.selectedPerson.id;
        console.log('Sales person updated');
    });
    
    // when all finished loading
    $q.all([clients, sales, items, quotes]).then(function () {
        // when udpate
        if ($scope.isUpdate) {
            //Create Quotation
            $scope.pageTitle = "Edit Quotation";
            $scope.pageTitleIcon = "fa fa-pencil";
    
            //init quotaion details
            quotationService.get($routeParams.quotationId).success(function (data, status) {
                $scope.quotation = data;
                //get clients
                $scope.selectedClient = _.findWhere($scope.clients, {id: $scope.quotation.client_id});
                console.log('Client preselected');
                //get sales person
                $scope.selectedPerson = _.findWhere($scope.sales_persons, {id: $scope.quotation.sales_person_id});
                console.log('Sales  person preselected');
            });
        } else {
            //when insert
            $scope.selectedClient = $scope.clients[0];
            $scope.selectedPerson = $scope.sales_persons[0];
            $scope.quotation.items.push({
                'item': null,
                'quantity': 0.00,
                'rate': 0.00
            });
            if (qty.auto_generate) {
                $scope.quotation.quotation_number = $scope.qty.prefix_string + 1000 + Math.floor((Math.random() * 100000) + 1);
            }
        }
    });