John John - 1 year ago 154
React JSX Question

Filtering JSON in React

I'm loading some JSON data using FETCH. I'm trying to add/create a simple filtering functionality on the content displayed.

I'm getting this error:

Uncaught TypeError: Cannot read property 'toLowerCase' of undefined

Any idea what could be causing this error?

This my code so far:

let Table = React.createClass({
getInitialState: function(){
return {
accounts: [{
"product": "Fixed Saver",
"interestRate": 2.20,
"minimumDeposit": 500,
"interestType": "Fixed"
}],
searchString: ''
}
},
componentDidMount: function(){
fetch('http://localhost:8888/table/json/accounts.json')
.then(response => {
return response.json()
})
.then(json => {
this.setState({accounts: json})
});
},
handleChange: function(e){
this.setState({searchString:e.target.value});
},
render: function(){
var libraries,
libraries = this.state.accounts,
searchString = this.state.searchString.trim().toLowerCase();

if(searchString.length > 0){
libraries = libraries.filter(l => {
return l.name.toLowerCase().match( searchString );
});
}

return (
<div className="container">

<input type="text" value={this.state.searchString} onChange={this.handleChange} placeholder="Type here" />

<ul className="header clearfix">
<li>Product</li>
<li>Interest rate</li>
<li>Minimum deposit</li>
<li>Interest type</li>
</ul>

{libraries.map(l => {
return (
<div className="account clearfix" key={l.id}>
<div className="product">{l.product}</div>
<div>{l.interestRate} %</div>
<div>£ {l.minimumDeposit}</div>
<div>{l.interestType}</div>
</div>
)
})}
</div>
)
}
});

let App = React.createClass({
render: function(){
return(
<Table />
);
}
});

ReactDOM.render( <App />, document.getElementById('table') );


JSON

[
{
"id": 1,
"product": "Fixed Saver",
"interestRate": 2.20,
"minimumDeposit": 500,
"interestType": "Fixed"
},
{
"id": 2,
"product": "Fixed Saver",
"interestRate": 1.50,
"minimumDeposit": 0,
"interestType": "Tracker"
},
{
"id": 3,
"product": "Offset Saver",
"interestRate": 1.8,
"minimumDeposit": 1000,
"interestType": "Fixed"
}
]

Answer Source

Seem that you got the error from this line

libraries = libraries.filter(l => {
  return l.name.toLowerCase().match( searchString );
});

Because of l.name is undefined. You can check again your JSON data. It doesn't have name attribute, seem that it is product.

You should not modify your state directly by: libraries = libraries.filter... State should be updated by setState function. In this case you should create temporary variable to display the results instead of directly use libraries variable. I believe if your sample is worked, you only may search for the first time and next time the results will be only in your last search results, though.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download