Newbie question: Use and bind {{input}} inside a component


#1

Hi there,

Sorry if this is a silly question. I am in the middle of the steepest part of the learning curve and trying to get a simple app going as a learning tool for myself, and my google-fu is failing me in understanding how to do this;

I have a component that is basically a list of model objects with some filtering options. The filter option relevant to this discussion is a free-text search. I want to have an {{input}} that is is bound to some value that affects the result list whenever it is updated.

{{input type=text value=filterString}}

In my poor understanding of Ember, I would have bound the value of the input to a string property, and have my filteredMatches computed property depend on that. However, if I define that property as such:

filteredMatches: Ember.computed.filter('matches', 'filterString', function(match, index, array) {

I get an error in the console log:

Uncaught TypeError: callback.call is not a function

If I remove the reference to ‘filterString’, it works as expected, but of course the filtering is not updated when I type something into the input.

So with my limited knowledge of Ember, I am stuck with this; Is the input actually binding to filterString on the controller, not the component? I do not use explicit controllers as I understand they will be going away. If that is the case, how can I have a computed property in my component depend on a controller property?

If that is not the case (i.e. controllers are not involved), how can I bind the input to a component property and react to value changes accordingly?

ember -v
version: 2.3.0-beta.2
node: 5.6.0
npm: 2.14.10
os: win32 x64

Thanks for any help, and again, sorry if this question is stupid!

Edit: I see now that my question belongs on Stack Overflow. If desired, I will delete it from here.


#2

Do it this way

>  Ember.computed.filter('matches', function(match, index, array) {
>     // Check for the logic here, say 
>     // return match===this.get('filterString');
> }

#3

Thanks for your reply. I got some replies on Stack Overflow that had me understand that the Ember.computed.filter function only allowed a single property to react on.

However, would your code react to filterString changing?


#4

No it will not.

You can try this,

matchedList: Ember.computed.filter(...)

computedList: Ember.computed('filterString', function() {
 return this.get('matchedList')
} )

#5

I suggest you to revamp the code. there’s no need to reopen the route when the route is active.

Just add getControllerAttr property in the route.

  getControllerAttr: function(propertyNamer) {
     return this.get('controller').get(propertyName); 
  },

#6

Thanks for your suggestions - I ended up with something relatively simple from an answer on Stack Overflow:

filteredMatches: Ember.computed('matches', 'filterString', {
    get() {
        return this.get('matches').filter(item => item.get('Description').indexOf(this.get('filterString')) >= 0);
    }
}),

The actual filter function will be more advanced than this, but the important part is that it seems more elegant (to my untrained eye) to just use Ember.computed to trigger on multiple properties, and then just do the actual filtering inside the get().