Populate view with data from web-service/API - reactjs

I am trying to use data for an API in React Native to create multiple views.
I have used the code below but the page renders before the web service response so i keep this error:
Unhandled JS Exception: null is not an object (evaluating 'this.state.user.map')
export default class Component6 extends Component {
constructor(props) {
super(props);
this.state = {
user: null
}
}
componentDidMount() {
this.fetchUsers();
}
fetchUsers() {
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.json())
.then((response) => {
this.setState({
});
});
}
render() {
contents = this.state.user.map(function (item) {
return (
<View key={item.id} style={styles.content}>
<Text>{item.email}</Text>
</View>
);
});
return (
{contents}
);
}
}
AppRegistry.registerComponent('Component6', () => Component6);

You can provide an 'if' statement, and also its better to move your contents outside of render so it's not redefining it on every render:
export default class Component6 extends Component {
constructor(props) {
super(props);
this.state = {
user: null
}
}
componentDidMount() {
this.fetchUsers();
}
fetchUsers() {
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.json())
.then((response) => {
item = this.viewconstur(response),
this.setState({
user: item
});
});
}
renderContents = () => {
if (this.state.user) {
this.state.user.map((item) => (
<View key={item.id} style={styles.content}>
<Text>{item.email}</Text>
</View>
));
}
}
render() {
return (
<View>
{this.renderContents()}
</View>
);
}
}

Related

getting 'Invariant Violation: `refreshing` prop must be set as a boolean in order to use `onRefresh`, but got `undefined`'

When the home screen loads I get 'Invariant Violation: refreshing prop must be set as a boolean in order to use onRefresh, but got undefined' please help.
class Home extends Component {
constructor(props) {
super(props)
this.state = {
suggestionList:[],
refreshing:false,
};
}
componentWillReceiveProps(nextProps){
this.setState({
suggestionList: nextProps.result.suggestionsArray ,
lastSuggestionKey : nextProps.result.lastSuggestionKey,
refreshing : false
});
}
handleRowPress = (item) => {
this.props.navigation.navigate('UserDetails', item);
};
handleMoreRequest = () => {
this.props.getOld(this.state.lastSuggestionKey);
};
handleRefresh = () => {
this.setState({
lastSuggestionKey: '',
refreshing: true
});
this.props.getAll();
};
componentWillMount() {
this.props.getAll();
}
render() {
return (
<View style={styles.containerStyle}>
<FlatList
style={{backgroundColor: colors.background}}
data={this.state.suggestionList}
renderItem={(item) =>
<CardItem contact={item.item}
onPress={() => this.handleRowPress(item)}
onCommentPress={() => this.props.navigation.navigate('SuggestionList')}/>
}
keyExtractor={item => item.suggestionid}
refeshing={this.state.refreshing}
onRefresh={() => this.handleRefresh()}
onEndReached={this.handleMoreRequest}
onEndReachedThreshold={0.7}
/>
</View>
);
}
}
const styles = StyleSheet.create({
containerStyle:{
flex:1,
backgroundColor: colors.background
},
});
function mapStateToProps({ suggestion }) {
return {
result: suggestion.result,
};
}
export default connect(mapStateToProps, actions)(Home);
You have a typo on your FlatList props, it should be refreshing instead of refeshing.

adding console.log to the class body causes error

when i add that console.log(3); to the class below it throws error
class AlbumList extends Component {
state ={ albums: [] };
console.log(3);
componentWillMount() {
console.log(4);
axios.get('https://rallycoding.herokuapp.com/api/music_albums')
.then(response => this.setState({ albums: response.data }));
}
renderAlbums() {
console.log(5);
return this.state.albums.map(
album => <AlbumDetail key={album.title} myAlbum={album} />
);
}
render() {
console.log(6);
return (
<View>
{this.renderAlbums()}
</View>
);
}
}
You need to put console.log(3) inside any method, example you can add it on componentDidMount()
componentDidMount() {
console.log(3)
}

how do I dynamically render title as component

I have a scene:
<Scene key="myFeed" component={myFeed} renderTitle={level}/>
In which I use the component to display the "title".
This function:
const level = () => {
return (
<Level/>
)
}
This component:
export class Level extends Component {
constructor(props) {
super(props);
this.state = {
progressBar: {},
loading: true,
};
}
connection() {
myApi.getServer('/user/level/', (data) => {
this.setState({loading: false, progressBar: data});
}, (err) => {
console.log(err.message);
this.setState({loading: false});
})
}
render() {
return(
<View style={styles.topBarCenterSlider}>
<View style={styles.topBarSlider}>
<View style={[styles.topBarStatus, {width: this.state.progressBar.level["progress"] + '%' : 0}]}/>
</View>
</View>
</View>
);
}
}
I need to change the component after the server response.
Help please, and sorry for my English))
I see you dont invoke "connection()". Put in componentWiLlMount
componentWillMount() {
this.connection();
}

state is empty in first render

following code give me this error : "Cannot read property 'CityName' of undefined" . but when I debug the code data state is empty only in first render and after that data has received the data from API. Is there any way to force the render to ignore the first empty state?
class profile extends Component {
constructor(props) {
super(props);
this.state = {
data :[],
};
}
componentWillMount() {
axios.get(BASE_URL + 'user/' + 1)
.then(response => this.setState({data: response.data.Result}))
.catch(error => console.log(error));
}
render() {
return (
<View>
<Text>{this.state.data.Profile.CityName}</Text>
</View>
);
}
}
In the first render this.state.data is an empty array so you should put a control for that onto your render method, assuming your network call is returning an array:
render() {
const {data = []} = this.state;
return (
data.map((record, index) => <View key={index}>
<Text>{record.Profile.CityName}</Text>
</View>)
);
}
}
Otherwise if your network request returns an object, then it should be something like:
render() {
//You may like to show loading indicator while retrieving data:
const {data = undefined} = this.state;
if(data) {
return (
<View>
<Text>{this.state.data.Profile.CityName}</Text>
</View>
);
}else{
return <View><Text>Is loading</Text></View>
}
}
You have defined data as empty array and then you are assigning it to object. Instead of intializing it as an empty array, intialize it as null.
class profile extends Component {
constructor(props) {
super(props);
this.state = {
data :null,
};
}
componentWillMount() {
axios.get(BASE_URL + 'user/' + 1)
.then(response => this.setState({data: response.data.Result}))
.catch(error => console.log(error));
}
render() {
return (
<View>
{this.state.data !== null ? <Text>{this.state.data.Profile.CityName}</Text> : <Text>Please Wait</Text>}
</View>
);
}
}

passing extraData to FlatList isn't working

I followed https://facebook.github.io/react-native/releases/next/docs/flatlist.html to make a FlatList and also passed this.state to extraData but still, once I delete an item, the item is still shown. I have also logged this.state to make sure the item is deleted and it indeed did. My code is below:
class DescriptionItem extends React.PureComponent {
render() {
return (
<TouchableOpacity
style={this.props.containerStyle}
onPress={(event) => {this.props.onPress(this.props.value)}}>
<Text style={this.props.style}>{this.props.value}</Text>
</TouchableOpacity>
)
}
}
export default class CardWorkDescriptionsList extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
loading: false,
data: [],
error: null,
refreshing: false,
};
}
_notifyItemSelected(text) {
if(this.props.onItemSelected) {
this.props.onItemSelected(text)
}
}
_onItemSelected = (selectedItem) => {
var array = this.state.data;
var index = array.indexOf(selectedItem)
array.splice(index, 1);
console.log(array)
this.setState({data: array });
console.log("yeah",this.state.data)
this._notifyItemSelected(selectedItem);
}
makeRemoteRequest = () => {
//TODO: fetch data
this.setState({data: descriptionsFake})
}
componentDidMount() {
this.makeRemoteRequest();
}
render() {
return (
<View style={styles.cardLight}>
<FlatList
data={this.state.data}
extraData={this.state}
renderItem={(item) => (
<DescriptionItem
containerStyle={styles.itemContainer}
style={styles.content}
value={item.item}
onPress={(selectedItem)=>this._onItemSelected(selectedItem)}/>
)}
keyExtractor={item => item.substring(0,20)}
/>
</View>
);
}
}
Try extending React.Component instead of PureComponent

Resources