3

I'm writing a website using angular-material in which I use the auto-complete. Within this autocomplete (codepen here) there is a function which returns the searchresults from a local array of demo search-items which (simplified) looks like this:

function querySearch (query) {
    var results = query ? self.repos.filter( createFilterFor(query) ) : self.repos, deferred;
    return results;
}

I now want to edit this code so that I can query the server after typing each letter. So I wrote the angular code to query the server and return a promise, as instructed here:

function querySearch (query) {
    return $http.get('/ajax/user/search/' + query).then(function(data){
        console.log(data); // I've got the data here. All fine.
        return data.data;
    });
}

Unfortunately this doesn't really work; the server gets queried fine, but I see an empty list of suggestions as you can see below:

enter image description here

Does anybody know how I can solve this issue? All tips are welcome!

Community
  • 1
  • 1
H_C
  • 337
  • 1
  • 7
  • 16
  • Sorry - do you mean have it requery for the auto complete answers each time you type a letter? – ajmajmajma Jul 16 '15 at 12:37
  • @ajmajmajma - Yes indeed – H_C Jul 16 '15 at 12:38
  • The example does that - https://material.angularjs.org/latest/#/demo/material.components.autocomplete , check off simulate query, and disable cache – ajmajmajma Jul 16 '15 at 12:38
  • @ajmajmajma - I see the code with the $q and the timeout, but I wouldn't know how to edit that so that I can call my endpoint with it. Any tips would really help me out here.. :-) – H_C Jul 16 '15 at 12:41
  • Do you mean the querySearch function in that example? It just sets up a promise, so you'd pretty much replace the $timeout with the actual call. The point of this being I think what you want is already built in :) – ajmajmajma Jul 16 '15 at 12:43
  • @ajmajmajma - Yes, awesome! You made me look at it another time, and thanks to you tip I finally fixed it! If you add your suggestion as an answer, I can accept it. – H_C Jul 16 '15 at 12:58
  • No problem, glad I could help, angular material is awesome! – ajmajmajma Jul 16 '15 at 13:03

2 Answers2

2

Check out the example here and click off simulate query and disable caching of queries - https://material.angularjs.org/latest/#/demo/material.components.autocomplete

Just make sure you disable cache md-no-cache="false" if you truly want it to fire every time and set md-min-length="0"

You just want to replace the timeout they have to mock the query with your actual query

function querySearch (query) {
  var results = query ? self.states.filter( createFilterFor(query) ) : self.states,
      deferred;
  if (self.simulateQuery) {
    deferred = $q.defer();
    //repalce this
    $timeout(function () { deferred.resolve( results ); }, Math.random() * 1000, false);
    return deferred.promise;
  } else {
    return results;
  }
}

And return your promise accordingly.

ajmajmajma
  • 13,712
  • 24
  • 79
  • 133
0

One quickfix would be to just return the function as:

function querySearch (query) {
    return $http.get('/ajax/user/search/' + query).success(function(data){
        console.log(data); // I've got the data here. All fine.
        return data.data;
    });
}

and then in the view change the call to:

md-items="item in ctrl.querySearch(ctrl.searchText)()"

therefore executing the function you return now.

(Codepen to showcase the solution: http://codepen.io/anon/pen/qdyEBy)

mhafellner
  • 458
  • 3
  • 9
  • I tried your suggestion, but I get a `TypeError: Cannot read property '0' of null` when typing. I tried removing the `()` at the end of the `md-items` line, but that leaves me with the same result: an empty list. Any more ideas? – H_C Jul 16 '15 at 12:51
  • That's a long shot but do you really want to return `data.data` and not just `data`? – mhafellner Jul 16 '15 at 12:53