Reputation: 219
I'm making AJAX request inside of a React function while making references to the state in the React class. However, I'm getting a TypeError where the reference to the state is undefined when I enter the AJAX request.
Here's my code snippet, I"m unsure how to proceed here. Where am I losing context?
class BugList extends React.Component {
constructor() {
super();
this.state = {
bugs: [],
};
}
addBug(bug) {
$.ajax({
type: 'POST', url: '/api/bugs', contentType: 'application/json', data:JSON.stringify(bug),
success: function(data) {
var bug = data;
var bugsModified = this.state.bugs.concat(bug);
this.setState({bugs: bugsModified});
}.bind(this),
error: function(xhr, status, err) {
console.log("error adding bug: ", err);
}
});
}
componentDidMount() {
$.ajax('/api/bugs').done(function(data) {
this.setState({bugs: data})
}.bind(this));
}
render() {
return(
<div>
<h1>Bug Tracker</h1>
<BugFilter />
<hr />
<BugTable bugs={this.state.bugs}/>
<hr />
<BugAdd addBug={this.addBug}/>
</div>
);
}
}
The problematic line in question:
var bugsModified = this.state.bugs.concat(bug);
The error log:
Uncaught TypeError: Cannot read property 'bugs' of undefined
Upvotes: 1
Views: 402
Reputation: 281950
Even though you have bound the ajax success function you forgot to bind the addBug
function
You can make use of arrow function to do that like
class BugList extends React.Component {
constructor() {
super();
this.state = {
bugs: [],
};
}
addBug(bug) {
$.ajax({
type: 'POST', url: '/api/bugs', contentType: 'application/json', data:JSON.stringify(bug),
success: function(data) {
var bug = data;
var bugsModified = this.state.bugs.concat(bug);
this.setState({bugs: bugsModified});
}.bind(this),
error: function(xhr, status, err) {
console.log("error adding bug: ", err);
}
});
}
componentDidMount() {
$.ajax('/api/bugs').done(function(data) {
this.setState({bugs: data})
}.bind(this));
}
render() {
return(
<div>
<h1>Bug Tracker</h1>
<BugFilter />
<hr />
<BugTable bugs={this.state.bugs}/>
<hr />
<BugAdd addBug={(data) => this.addBug(data)}/>
</div>
);
}
}
Upvotes: 0
Reputation: 6857
it is a scope issue, try..
addBug(bug) {
***var that = this;***
$.ajax({
type: 'POST', url: '/api/bugs', contentType: 'application/json', data:JSON.stringify(bug),
success: function(data) {
var bug = data;
var bugsModified = ***that.state.bugs.concat(bug)***;
this.setState({bugs: bugsModified});
}.bind(this),
error: function(xhr, status, err) {
console.log("error adding bug: ", err);
}
});
}
or you can also try
constructor() {
super();
this.state = {
bugs: [],
};
this.addbugs = this.addbugs.bind(this);
}
and keep the rest as it was
Upvotes: 1
Reputation: 104499
You need to bind
the addBug method
, use this:
<BugAdd addBug={this.addBug.bind(this)}/>
You are passing a method from parent component to child component, bind
that method
in parent component, like this:
<BugAdd addBug={this.addBug.bind(this)}/>
or you can define the binding
in the constructor
also, like this:
constructor() {
super();
this.state = {
bugs: [],
};
this.addBug = this.addBug.bind(this);
}
and use directly:
<BugAdd addBug={this.addBug}/>
Upvotes: 1