Search code examples
javascriptember.jsember-cli

filter an ember model


I'm more of a backend guy trying to get a bit into front end specifically Ember. I've already built an api now I'm trying to create almost like a autocomplete search (similar to Angulars filter | ngModel). Here is my api:

 {
  data: [
    {
      id: 6,
      name: "Alexandrine Skiles",
      links: [
        {
          rel: "self",
          uri: "/api/v1/address-book/alexandrine-skiles"
        }
      ]
    },
    {
      id: 33,
      name: "Ally Johns",
      links: [
        {
          rel: "self",
          uri: "/api/v1/address-book/ally-johns"
        }
      ]
    }
  ]
}

here is my route:

export default Ember.Route.extend({
    model: function(){
        var adapter = AddressBookAdapter.create();
        var companies =  adapter.findAll();
        return companies;
    }
});

Here is the adapter:

export default Ember.Object.extend({
    findAll: function(){
        return ajax('http://localhost:8000/api/v1/address-book/companies')
            .then(function(response){
                return response.data;
            });
    }
});

and here is the controller:

export default Ember.ArrayController.extend({
    searchKeyword: null,

    searchResults: function(){
        var searchText = this.get('searchText');

        if( ! searchText) return;

        var adapter = AddressBookAdapter.create();
        var companies =  adapter.findAll();

        var regex = new RegExp(searchText, 'i');

        return companies.then(function(data){
            return data.filter(function(company){
                return company.name.match(regex);
            });
        });
    }.property('searchText')
});

here is the html:

{{input type="text" value=searchText class="form-control" id="inputContactSearch" }}

{{#if searchResults}}
        {{#each searchResult in searchResults}}
            <tr>
                <td>{{searchRe}}</td>
            </tr>
        {{/each}}
{{else}}
        {{#each m in model}}
            <tr>
                <td><a href="{{m.links.uri}}">{{m.name}}</a></td>
            </tr>
        {{/each}}
 {{/if}}        

Now I know that the way I have my handlebars set up is not the best with the If and Else statements. I'm just trying to make it work I feel like I'm very close I get the error that the each loop needs to be an array not an object. But Model is an object not and array but it still loops it correctly. Is this the way to go about this or I'm I doing this completely wrong. Is there just a straight Model filter like Angular or is this way still doable. Thanks in advance


Solution

  • So the problem is that you are trying to iterate over the promise, not the resolved value of the promise. To be clear, the adapter returns a promise, and in your computed property, you are returning this same promise. When a promise resolves, it doesn't become the resolved values. It executes the success or failure functions. It's up to you assign this value appropriately.

    Change your controller to use the model returned from the route's model hook. This hook blocks on promises so the value of your controller's model is the companies.

    export default Ember.ArrayController.extend({
        searchKeyword: null,
    
        searchResults: function(){
            var searchText = this.get('searchText');
    
            if( ! searchText) return;
    
            //YOUVE ALREADY GOT THE COMPANIES DONT GO BACK TO THE SERVICE
            var companies =  this.get('model');
    
            var regex = new RegExp(searchText, 'i');
    
            return companies.filter(function(company){
                return company.name.match(regex);
            });
        }.property('searchText', 'model')
    });