Reputation: 2487
I am new to React Native and am trying to parse XML into a FlatList and then save it to the State object. In order to parse the XML, I am using react-native-xml2js and the simple function, parseString. The parseString has a callback function and I am trying to use the setState function within that callback function. However, "this" is undefined in the callback and, when I try to pass "this" as a different variable (in this case, "self"), it's still undefined. What am I doing wrong here?
export default class PostList extends Component<{}>
{
constructor(props) {
super(props);
this._executeQuery('https://website.com/xml-feed/');
this.state = {
resultsLoaded: false,
results: false,
};
};
_keyExtractor = (item, index) => index;
_renderItem = ({item, index}) => (
<ListItem
item={item}
index={index}
onPressItem={this._onPressItem}
/>
);
_renderList = (response) => {
return <FlatList
data={response.rss.channel[0].item}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
/>;
};
_handleResponse = (response) => {
var parseString = require('react-native-xml2js').parseString;
var self = this;
this.setState({ resultsLoaded: true });
parseString(response, function (err, result, self) {
console.log(self);
self.setState({ resultsLoaded: true, results: self._renderList(result) });
});
};
_executeQuery = (query) => {
fetch(query)
.then(response => response.text())
.then(str => this._handleResponse(str))
.catch(error =>
console.log('ERROR: '+error)
);
};
render() {
const results = this.state.resultsLoaded ?
this.state.results : null;
const loading = !this.state.resultsLoaded ?
(<View><Text style={styles.description}>
Loading Blog Posts
</Text>
<ActivityIndicator size='large'/></View>) : null;
console.log(this.state.resultsLoaded);
return (
<View style={styles.container}>
{loading}
{results}
</View>
);
};
}
Upvotes: 1
Views: 1180
Reputation: 5167
Remove self
parameter from the callback function:
_handleResponse = (response) => {
var parseString = require('react-native-xml2js').parseString;
var self = this;
this.setState({ resultsLoaded: true });
parseString(response, function (err, result) {
console.log(self);
self.setState({ resultsLoaded: true, results: self._renderList(result) });
});
};
Having self
as a parameter will always return undefined
Another option would be to bind this
with the callback function:
parseString(response, function (err, result) {
console.log(this);
self.setState({ resultsLoaded: true, results: self._renderList(result) });
}.bind(this));
And finally you could make use of ES6 Arrow functions:
parseString(response, (err, result) => {
console.log(this);
self.setState({ resultsLoaded: true, results: self._renderList(result) });
});
Upvotes: 2
Reputation: 22797
You'll have access to this
by removing the arrow, declare function directly:
_handleResponse(response) {
var parseString = require('react-native-xml2js').parseString;
var self = this;
this.setState({ resultsLoaded: true });
parseString(response, function (err, result, self) {
console.log(self);
self.setState({ resultsLoaded: true, results: self._renderList(result) });
});
};
There's a detail answer about Arrow Function and this.
Upvotes: 0