Reputation: 689
I am new to javascript and am working on a real time search app where I am using react to get the search results. I am using ajax to get the data from a url as I had to use jsonp to get around server constraint. Although I am able to get the result in console.log in my searchForTerm function but not in render function as I am unable to bind it to my variable there properly. So I am unable to get the result that I want on screen.
Please check my jsfiddle
Here is my code:
// var test = {};
// var json = {"F": {"symbol": "F", "name": "Ford Motor", "bidPrice": 13.43, "askPrice": 13.52}};
// test.data = [json];
// If i use the above variable and feed them to data during initialization,
// then it works. But when i get the same data from server i am not able to
// get the same update on my screen.
var SearchStock = React.createClass({
getInitialState: function() {
return {searchString: '', data: [], quantity: ''};
},
componentWillMount: function() {
// Get the initial terms
this.doSearch();
},
componentWillUnmount: function() {
this.serverRequest.abort();
},
doSearch: function(term) {
this.serverRequest = this.searchForTerm(term || '').then(this.handleSearchResult);
},
searchForTerm: function (term) {
var url = 'http://data.benzinga.com/rest/richquoteDelayed?symbols=' + term;
return $.ajax({
url,
dataType: 'jsonp',
success: function (data) {
console.log("in search", JSON.stringify(data));
this.setState({data: [JSON.stringify(data)]});
}.bind(this)
});
},
handleSearchResult: function(quote) {
this.setState(quote);
},
handleChange: function(e) {
this.setState({searchString: e.target.value});
// The server doesn't seem to respond to lowercase values
this.doSearch(e.target.value.toUpperCase());
},
buy: function(e){
if(!term.quantity){
term.quantity = e;
} else {
term.quantity = term.quantity + e;
}
return term.quantity;
},
sell: function(e){
term.quantity = term.quantity - e;
return term.quantity;
},
viewStock: function(e){
searchForTerm(e);
},
render: function() {
var stocks = this.state.data;
console.log("in render", stocks);
var searchString = this.state.searchString.trim().toLowerCase();
if (searchString.length > 0) {
stocks = stocks.filter(function(l) {
// return l.name.toLowerCase().match(searchString);
return l[Object.keys(l)[0]]["symbol"].toLowerCase().match(searchString);
});
}
return (
<div>
<div id='searchResult'>
<input type="text" value={this.state.searchString} onChange={this.handleChange} placeholder="Type here" />
<ul>
{stocks.map(function(l) {
return <div>
<h3>{l[Object.keys(l)[0]]["name"]}</h3>
<table class="table table-striped table-bordered">
<tr>
<th>Bid</th>
<th>Ask</th>
</tr>
<tr>
<td>{l[Object.keys(l)[0]]["bidPrice"]}</td>
<td>{l[Object.keys(l)[0]]["askPrice"]}</td>
</tr>
</table>
</div>
})}
</ul>
<input type="text" value={this.state.quantity} placeholder="Quantity" />
<input type="button" value="Buy" onClick={this.buy} />
<input type="button" value="Sell" onClick={this.sell} />
</div>
<div id='currentPorfolio'>
<h5>Current Portfolio</h5>
<h5>$100,000 This needs a disabled text box with value comming from a variable with initial value as $100000</h5>
<table class="table table-striped table-bordered">
<tr>
<th>Company</th>
<th>Quantity</th>
<th>Price Paid</th>
<th></th>
</tr>
{stocks.map(function(l) {
return <tr>
<td>{l[Object.keys(l)[0]]["name"]}</td>
<td>{l[Object.keys(l)[0]]["quantity"]}</td>
<td>{l[Object.keys(l)[0]]["bidPrice"]}</td>
<td>{<input type="button" value="View Stock"/>}</td>
</tr>
})}
</table>
</div>
</div>
);
}
});
ReactDOM.render( <SearchStock />, document.getElementById('container'));
I feel this should be related to scope of variables and the way they are being updated. But i would appreciate if anyone can help me out here as I can see the results in console log but not on the screen.
I have to work on debouncing too after this as right now this is sending requests to the server even when there is no change. Is there any better way to use handleChange to call only when there is a change in text box?
Apologies if I am missing something here as I am fairly new to javascript and react. And I have always been confused with the way javascript deals with scoping.
Upvotes: 0
Views: 1402
Reputation: 689
I was able to work it out with onBlur instead of onChange in react. Here is an article that i referred and helps us understand the difference in javascripts onchange() and reacts onChange() property and how onBlur() in react is equivalent to onchange() of javascript.
I hope this helps someone who was confused between the two functions.
Upvotes: 1
Reputation: 4863
There are a few problems here, the first one might be that this
does not refer to the React component within jQuery's ajax()
method (I can't tell because the URL doesn't work for me).
Try this, which will give you a reference to setState from outside the jQuery code.
searchForTerm: function (term) {
const setState = state => this.setState(state);
var url = 'http://data.benzinga.com/rest/richquoteDelayed?symbols=' + term;
return $.ajax({
url,
dataType: 'jsonp',
success: function (data) {// your code here
console.log("in search", JSON.stringify(data));
setState({data: [JSON.stringify(data)]});
}.bind(this)
});
},
If this doesn't help, I would suggest fixing all the errors showing in the console, or removing all the code that causes them (for the example). It will be easier for others to help if there is a simple example of something not working as you expect.
Another issue you'll run into is that variables are scoped to the functions where they are defined. Thus in buy()
and sell()
, term
is undefined.
Upvotes: 1