$http issue - Values can't be returned before a promise is resolved in md-autocomplete Angular Material
<p>I'm using Angular Material <code>md-autocomplete</code> in my project. In that I'm getting the suggest listing from the Service Host via ajax call using <code>$http</code> service.</p>

<blockquote>
  <p><strong>Issue</strong>: $http issue - Values can't be returned before a promise is
  resolved in <strong><code>md-autocomplete</code></strong> Angular Material</p>
  
  <p><strong>My Requirement</strong>: I need an updated Suggestion List using remote data
  sources in <strong><code>md-autocomplete</code></strong> Angular Material - Ajax <code>$http</code> service.</p>
</blockquote>

<p>I used the approach as mentioned in Angular Material link <a href="https://material.angularjs.org/latest/demo/autocomplete" rel="nofollow noreferrer">https://material.angularjs.org/latest/demo/autocomplete</a></p>

<p>Source Code:</p>

<p><strong>Scenario 1:</strong></p>

<p>HTML Source Code:</p>

<pre><code>&lt;md-autocomplete flex required
    md-input-name="autocompleteField"
    md-no-cache="true"
    md-input-minlength="3"
    md-input-maxlength="18"
    md-selected-item="SelectedItem"
    md-search-text="searchText"
    md-items="item in querySearch(searchText)"
    md-item-text="item.country" Placeholder="Enter ID" style="height:38px !important;"&gt;
    &lt;md-item-template&gt;
        &lt;span class="item-title"&gt;
            &lt;span md-highlight-text="searchText" md-highlight-flags="^i"&gt; {{item.country}} &lt;/span&gt;
    &lt;/md-item-template&gt;
&lt;/md-autocomplete&gt;
</code></pre>

<p>AngularJS Script:</p>

<pre><code>//bind the autocomplete list when text change
function querySearch(query) {
    var results = [];
    $scope.searchText = $scope.searchText.trim();
    if (query.length &gt;=3) {
        results = LoadAutocomplete(query);
    }
    return results;
}

//load the list from the service call
function LoadAutocomplete(id) {
    var countryList = [];
    $http({
            method: "post",
            url: "https://www.bbminfo.com/sample.php",
            params: {
                token: id
            }
        })
        .success(function (response) {
            countryList = response.records;
        });

        return countryList;
}
</code></pre>

<p><strong>Scenario 2:</strong></p>

<p>HTML with AngularJS Source Code:</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="false" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css"&gt;
    &lt;script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"&gt;&lt;/script&gt;
&lt;script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"&gt;&lt;/script&gt;
&lt;script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"&gt;&lt;/script&gt;
&lt;script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"&gt;&lt;/script&gt;

&lt;!-- Angular Material Library --&gt;
&lt;script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"&gt;&lt;/script&gt;
&lt;body&gt;

&lt;div ng-app="myApp" ng-controller="myCtrl"&gt; 

&lt;p&gt;Person to Select:&lt;/p&gt;

&lt;md-autocomplete
          ng-disabled="isDisabled"
          md-no-cache="noCache"
          md-selected-item="selectedItem"
          md-search-text-change="searchTextChange()"
          md-search-text="searchText"
          md-selected-item-change="selectedItemChange(item)"
          md-items="item in Person"
          md-item-text="item.Name"
          md-min-length="0"
          placeholder="Which is your favorite Person?"&gt;
        &lt;md-item-template&gt;
          &lt;span md-highlight-text="ctrl.searchText" md-highlight-flags="^i"&gt;{{item.country}}&lt;/span&gt;
        &lt;/md-item-template&gt;
        &lt;md-not-found&gt;
          No Person matching "{{searchText}}" were found.
        &lt;/md-not-found&gt;
      &lt;/md-autocomplete&gt;
      &lt;br/&gt;
&lt;/div&gt;

&lt;script&gt;
    var app = angular.module('myApp', ['ngMaterial']);

    app.controller('myCtrl', function ($scope, $http, $q) {

        $scope.searchText = "";
        $scope.Person = [];
        $scope.selectedItem = [];
        $scope.isDisabled = false;
        $scope.noCache = false;

        $scope.selectedItemChange = function (item) {
            alert("Item Changed");
        }
        $scope.searchTextChange = function () {

            $http({
                method: "POST",
                url: "https://www.bbminfo.com/sample.php",
                params: {
                    token: $scope.searchText
                }
            })
            .success(function (response) {
                $scope.Person = response.records;
            });
        }

    });
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
</div>
</div>
</p>

<p>In <strong>Scenario 1</strong>, I used the function to fetch the filtered list <code>md-items="item in querySearch(searchText)"</code>. But in <strong>Scenario 2</strong>, I used a <code>$scope</code> variable <code>md-items="item in Person"</code></p>

<p>Kindly refer the Snapshots</p>

<p><strong>Snapshot 1:</strong></p>

<p><a href="https://i.stack.imgur.com/eFQsT.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/eFQsT.png" alt="Autocomplete Listing Issue - UI"></a></p>

<p>Here I'm searching for <strong>indian</strong> but it shows the result for <strong>india</strong>. I debugged the issue in <strong>Firefox Browser Firebug</strong>, see the above <strong>Snapshot 1</strong> it shows, the request was sent for the search term <strong>indian</strong> via POST Method and I got the response of one matching items as a JSON Object successfully, which is shown in the bottom of <strong>SnapShot 1</strong></p>

<blockquote>
  <p>The issue I find out in this case, the Values can't be returned before
  a promise is resolved</p>
</blockquote>

<p><strong>Steps I tried:</strong></p>

<p><strong>Case 1</strong>: I used the AngularJS <code>filter</code> in UI <code>md-items="item in Person | filter: searchText"</code>, it gives the filtered list of previously fetched remote data not a currently fetched remote data. While on Backspacing the character in the textbox it shows the improper suggestion list.</p>

<p><strong>Case 2</strong>: I tried to update the changes in UI by calling <code>$scope.$apply()</code> within a <code>$http</code> service, but it fails. Because <code>$http</code> service calling the <code>$scope.$apply()</code> by default, show it throws me an error <strong>Error: [$rootScope:inprog]...</strong>. Finally in this attempt I failed.</p>

<p><strong>Case 3</strong>: I created a function, within the function I'm manually called the <code>$scope.$apply()</code>, within the function I manually pushed and poped one dummy item to the <code>$scope</code> variable which is bind in the <code>md-autocomplete</code>. But I failed in this attempt. Because here also I got a same output as same as in the snapshot.</p>

<pre><code>function Ctrlm($scope) {
    $scope.messageToUser = "You are done!";
    setTimeout(function () {
        $scope.$apply(function () {

            $scope.dummyCntry = [
                {
                    sno: 0,
                    country: ""
                },
            ];

            $scope.Person.push($scope.dummyCntry);

            var index = $scope.Person.indexOf($scope.dummyCntry);
            $scope.Person.splice(index, 1);

        });
    }, 10);
}
</code></pre>

<p><strong>Case 4</strong>: I did the same approach as like "Case 3" within the $scope.$watchCollection. Here also I got a setback.</p>

<pre><code>$scope.$watchCollection('Person', function (newData, oldDaata) {
    $scope.dummyCntry = [
                {
                    sno: 0,
                    country: ""
                },
            ];

    newData.push($scope.dummyCntry);

    var index = newData.indexOf($scope.dummyCntry);
    newData.splice(index, 1);
});
</code></pre>

<p><strong>Case 5</strong>: Instead of <code>$http</code> service, I used the <strong>jquery ajax call</strong>. In that I used the <code>$scope.apply()</code> to update the UI manually. I failed in this attempt once again, here also I got the same output.</p>

<pre><code>$scope.searchTextChange = function () {
    if (($scope.searchText != undefined) &amp;&amp; ($scope.searchText != null)) {

        $.ajax({
            type: 'GET',
            url: "https://www.bbminfo.com/sample.php?token=" + $scope.searchText,
            success: function (response) {
                $scope.$apply(function () {
                    $scope.Person = response.records;
                });
            },
            error: function (data) {
                $scope.$apply(function () {
                    $scope.Person = [];
                });
            },
            async: true
        });


    } else {
        $scope.Person = [];
    }
}
</code></pre>

<blockquote>
  <p>In all the attempts I can't able to fix the issue.</p>
</blockquote>

<p>@georgeawg <a href="https://stackoverflow.com/users/5535245/georgeawg">https://stackoverflow.com/users/5535245/georgeawg</a> suggested me to post a new question, he stated, "<em>write a new question that describes what you are actually trying to accomplish, include the desired behavior, a summary of the work you've done so far to solve the problem, and a description of the difficulty you are having solving it.</em>"</p>

<p>Reference Questions which I was posted in the earlier</p>

<p><strong>Post 1</strong>: <a href="http://www.stackoverflow.com/questions/35624977/md-items-is-not-updating-the-suggesion-list-properly-in-md-autocomplete-angular">http://www.stackoverflow.com/questions/35624977/md-items-is-not-updating-the-suggesion-list-properly-in-md-autocomplete-angular</a></p>

<p><strong>Post 2</strong>: <a href="http://www.stackoverflow.com/questions/35646077/manually-call-scope-apply-raise-error-on-ajax-call-error-rootscopeinprog">http://www.stackoverflow.com/questions/35646077/manually-call-scope-apply-raise-error-on-ajax-call-error-rootscopeinprog</a></p>

<blockquote>
  <p>My Requirement: I need an updated Suggestion List using remote data
  sources in Angular Material <code>md-autocomplete</code> - Ajax <code>$http</code> service.</p>
</blockquote>

<p>Kindly assist me in this regards.</p>

<blockquote>
  <p><strong>For Testing Purpose Use the following Source Code</strong></p>
</blockquote>

<p>Use the following URL for Remote Data Source: <a href="https://bbminfo.com/sample.php?token=ind" rel="nofollow noreferrer">https://bbminfo.com/sample.php?token=ind</a></p>

<p>The Remote Data Source URL contains the List of Countries Name.</p>

<blockquote>
  <p>Directly Test the Code by click the below <strong>Run Code Snippet</strong> button.</p>
</blockquote>

<p>Complete HTML with AngularJS Source Code:</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="false" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css"&gt;
&lt;script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"&gt;&lt;/script&gt;
&lt;script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"&gt;&lt;/script&gt;
&lt;script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"&gt;&lt;/script&gt;
&lt;script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"&gt;&lt;/script&gt;

&lt;!-- Angular Material Library --&gt;
&lt;script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"&gt;&lt;/script&gt;
&lt;body&gt;

&lt;div ng-app="myApp" ng-controller="myCtrl"&gt; 

&lt;p&gt;Country to Select:&lt;/p&gt;
&lt;md-content&gt;
&lt;md-autocomplete
          ng-disabled="isDisabled"
          md-no-cache="noCache"
          md-selected-item="selectedItem"
          md-search-text-change="searchTextChange()"
          md-search-text="searchText"
          md-selected-item-change="selectedItemChange(item)"
          md-items="item in Person"
          md-item-text="item.country"
          md-min-length="0"
          placeholder="Which is your favorite Country?"&gt;
        &lt;md-item-template&gt;
          &lt;span md-highlight-text="searchText" md-highlight-flags="^i"&gt;{{item.country}}&lt;/span&gt;
        &lt;/md-item-template&gt;
        &lt;md-not-found&gt;
          No Person matching "{{searchText}}" were found.
        &lt;/md-not-found&gt;
      &lt;/md-autocomplete&gt;
      &lt;/md-content&gt;
      &lt;br/&gt;
&lt;/div&gt;

&lt;script&gt;
    var app = angular.module('myApp', ['ngMaterial']);

    app.controller('myCtrl', function ($scope, $http, $q) {

        $scope.searchText = "";
        $scope.Person = [];
        $scope.selectedItem = [];
        $scope.isDisabled = false;
        $scope.noCache = false;

        $scope.selectedItemChange = function (item) {
            alert("Item Changed");
        }
        $scope.searchTextChange = function () {

            $http({
                method: "post",
                url: "https://www.bbminfo.com/sample.php",
                params: {
                    token: $scope.searchText
                }
            })
            .success(function (response) {
    $scope.Person = response.records;
            });
        }

    });
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
</div>
</div>
</p>