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