devdropper87 devdropper87 - 1 month ago 6
AngularJS Question

select drop downs and promises - briefly empty selects

I have two filters where the first influences the second before querying data to a remote server.

I have a select, which has its options in

$scope.locationCodes
. This select relies on another dropdown (customer). Once the customer is selected, I have the ID, and then pass that to the returned promise in the first function.

The issue 1:

As soon as I select a customer, if I really quickly go to select a location code (in codes dropdown), the options will be blank. If i blur and then try to select again, the options will show up, indicating there was a bit of a delay. What's the best way to handle this delay in the array being populated?

The code:

HTML:

<select data-ng-options="locationCode in locationCodes"></select>


JS:

$scope.getShipAbbleLocations = function (terminalId) {
var customerId = $scope.customer.id;
return Service.getShipAbbleLocations(customerId, terminalId).then(function (data) {
getLocationCodes(data);
_.defer(function () {
$scope.$apply();
})
});

};



function getLocationCodes(data) {
for (var i = 0; i < data.locationCodes.length; i++) {
$scope.locationCodes.push(["(" + data.locationCodes[i].shipThruLocationCode + ")", data.locationCodes[i].shipThruLocationId]);
}
$scope.$apply();
}


The issue 2:

The kicker is that the codes dropdown should be disabled until a customer is selected. I have been relying on a timeout in my controller to handle the disable by setting a delay for the 'enable' which allows time for the array to be populated. This works, but the issue re appears once you change customers and don't have to worry about the initial disable case.

I am wondering if there is a better way than timeouts (that hopefully shows a better understanding of angularjs/promises) to handle this delay/asynchronicity.

Answer

The best way is to show LOADER and disable the UI until your AJAX call is complete.

It is always a better practice to implement loader for async ajax calls.

You can implement the loader code in interceptors, so that for every request the loader will show up and you dont have to implement for every AJAX call, since its in the interceptor.