Reputation: 199
I passed filterText=this.state.filterText
to the Child Table to filter only the films which contain the letters which I've typed into searcher.
Inside Table
component I've created function CheckIfFiltered
to filter the films and to check if the table contains the "filterText".
The problem is that when I try to run it there is an Error:
"Uncaught TypeError: Cannot read property 'filterText' of undefined"
Although I've passed filterText
to a props, to the Table component. Please help me solve this problem.
var Row = React.createClass({
render: function(){
return(
<tr>
<td>{this.props.episode.title}</td>
<td><a href ="top">Link</a></td>
</tr>
);
}
});
var Table = React.createClass({
render: function(){
var CheckIfFiltered=function (episode, index, ar){
if (episode.title.toLowerCase().indexOf(this.props.filterText.toLowerCase()) > -1){
return true;
}
else {
return false;
}
}
var filter_rows = this.props.episodes.filter(CheckIfFiltered).map(function(episode){
return <Row episode={episode} key={episode.title} /> ;
});
return(
<div className="row spacer">
<div className="col-lg-4 col-lg-offset-4">
<table width="100%">
<tbody>{filter_rows}</tbody>
</table>
</div>
</div>
);
}
});
var Search = React.createClass({
changeFilteringSearch: function(){
this.props.changeFiltering(
this.refs.filterTextInput.value
);
},
render: function(){
return (
<div className="row ">
<div className="col-lg-4 col-lg-offset-4">
<input type="search" className="form-control" value = {this.props.filterText} ref="filterTextInput" onChange={this.changeFilteringSearch} className="form-control" placeholder="Search for episode" />
</div>
</div>
);
}
});
var FilterableEpisodesTable = React.createClass({
getInitialState: function() {
return {
filterText: 'qwerty'
};
},
changeFiltering: function(text){
this.setState({
filterText: text
});
},
render: function(){
return(
episodes=this.props.episodes,
<div>
<Search filterText={this.state.filterText} changeFiltering={this.changeFiltering}/>
<hr/>
<Table episodes={episodes} filterText={this.state.filterText}/>
</div>
);
}
});
var episodes = [{title : "Angular with Yeoman",},
{title : "Using D3 with Rickshaw and Angular",},
{title : "Canvas with paper.js",},
{title : "Express.js middleware",},
{title : "Metro",}
];
ReactDOM.render(
<FilterableEpisodesTable episodes = {episodes}/>,
document.getElementById('example')
);
Upvotes: 0
Views: 766
Reputation: 2452
CheckIfFiltered
runs in a different context as you’ve passed it to filter, so it just needs to be bound.
Either
var CheckIfFiltered=function( episode ){
if (episode.title.toLowerCase().indexOf(this.props.filterText.toLowerCase()) > -1){
return true;
} else {
return false;
}
}.bind( this )
or
var filter_rows = this.props.episodes.filter(CheckIfFiltered.bind( this )).map( ... )
should help you scope it correctly. Alternatively add it as a class method, I think React.createClass
autobinds functions but note that if you change to ES2015 syntax the JS native behaviour of never autobinding will take place so you'll have to bind it yourself.
React.createClass({
CheckIfFiltered: function( episode, index, ar ){
return episode.title.toLowerCase().indexOf(this.props.filterText.toLowerCase()) > -1 ? true : false
},
render: function() { ... }
})
Upvotes: 1
Reputation: 7045
I think this is a simple scope problem, check this and let me know if it helps.
render: function(){
var self = this;
var CheckIfFiltered=function (episode, index, ar){
if (episode.title.toLowerCase().indexOf(self.props.filterText.toLowerCase()) > -1){
return true;
}
else{
return false;
}
Upvotes: 0