2

I am using the angular bootstrap ui typeahead asynchronously to return an array of records, but can't get it to work. I've gotten the typeahead to work when the operation is performed synchronously, by downloading all the data on page load. The data looks the same in both cases; and it appears that the asynchronous version fails because the typeahead only gets a promise, not the returned data.

The angularjs controller looks like this:

Synchronous

vm.doctorList = [];

vm.doctorList = [];
function getAllDoctors() {
  agreementService.getAllDoctors()
    .then(function (response) {
      vm.doctorList = response.data;
  });
}

Asynchronous

vm.getExistingDoctor = function (value) {
  if (value.length > 2) {
    agreementService.getExistingDoctor(value)
      .then(function (response) {
          return response.data;
      });
  }
};

The HTML looks like this:

Synchronous

<input type="text" ng-model="vm.agreement.doctor.nameFull" 
       uib-typeahead="doctor as doctor.nameFull + ' (ClockID: ' + doctor.clockID + ')'  
                      for doctor in vm.doctorList | filter:{nameFull:$viewValue} | limitTo:8" 
       class="form-control bottom-none" typeahead-show-hint="true" typeahead-min-length="3" typeahead-on-select="vm.onDoctorSelect($item, $model, $label, $event)">

Asynchronous

<input type="text" ng-model="vm.agreement.doctor.nameFull" 
       uib-typeahead="doctor as doctor.nameFull + ' (ClockID: ' + doctor.clockID + ')' 
                      for doctor in vm.getExistingDoctor($viewValue) | filter:{nameFull:$viewValue} | limitTo:8" 
       class="form-control bottom-none" typeahead-show-hint="true" typeahead-min-length="3" 
       typeahead-on-select="vm.onDoctorSelect($item, $model, $label, $event)">

In both cases data returned from the controller looks like this:

[Object, Object]
0:Object
clockID:14
nameFull:"Doe, Jane"
__proto__:Object
1:Object
__proto__:Object

In the synchronous version, the typeahead acts as expected, but in the asynchronous version nothing happens as the user enters three or more characters.

What needs to be done to make the asynchronous version function correctly?

1 Answer 1

2

For async, you'll need to return a promise object. Assuming your agreementService returns the $http request/promise (which it seems to), your search function should look something like:

vm.getExistingDoctor = function (value) {
      return agreementService.getExistingDoctor(value).then(function (response) {
          return response.data;
      });
}

Note that I removed the check for the length of the value since the uibTypeahead directive already prevents it from calling data asynchronously if the minimum length isn't met. I also recommend using ng-options to define a debounce value, that way you're not calling your API on every keystroke. ng-options={debounce: 500}

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.