Getting Undefined in React native - react-native

import React, { Component } from 'react';
import { View, Text } from 'react-native';
class HttpExample extends Component {
state = {
data: ''
}
componentDidMount = () => {
fetch("https://jsonplaceholder.typicode.com/posts/1", { --this is fake url
method: 'POST',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded', // <-- Specifying the Content-Type
}),
body: "param1=value1&param2=value2" // <-- Post parameters
})
.then((response) =>
response.text()
)
.then((responseText) => {
alert(responseText.id);
this.setState({
data: responseText
})
})
.catch((error) => {
console.error(error);
});
}
render() {
return (
<View>
<Text>
{this.state.data.id}
</Text>
</View>
)
}
}
export default HttpExample;
if i use alert(ResponseText)
in alert i am getting o/p but as i tried to have individual value from my object it returns undefined
o/p: "id": "1",
"computeId": "USR00001" in alert

.then((response) => response.text())
to
.then((response) => response.json())
I guess you need json style response.

Related

React Native Logout Using Access Token Error

This is a simple app to login with API and logout. I retrieved Access Token when login. I navigated the access token to sidebar and trying to log out using logout function
SideBar.js
import React from 'react';
import { Text, Alert } from 'react-native';
import { Drawer,Container, Content, Header, Right, Button } from 'native-base';
export default class SideBar extends React.Component {
constructor(props) {
super(props)
this.state = {
token: this.props.usertoken
}
}
UserLogoutFunction = () =>{
const { token } = this.state;
fetch('https://api.idepoz.com/ncl/api/logout', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Authorization': `Bearer ${token}`,
},
body: JSON.stringify({
})
}).then((response) => response.json())
.then((responseJson) => {
console.log("token");
if(responseJson)
{
this.props.navigation.navigate('Login');
Alert.alert("Succesfully Logged Out");
}
else{
Alert.alert(responseJson);
}
}).catch((error) => {
console.error(error);
});
}
render() {
return (
<Container>
<Header>
</Header>
<Content>
<Button transparent onPress={ this.UserLogoutFunction } >
<Text style={{fontSize: 24}}>Log Out</Text>
</Button>
</Content>
</Container>
);
}
}
It returning NETWORK REQUEST FAILED.
The below function returned access token while login
UserLoginFunction = () =>{
const { UserName } = this.state ;
const { UserPassword } = this.state ;
fetch('https://api.idepoz.com/ncl/api/login', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: UserName,
password: UserPassword
})
}).then((response) => response.json())
.then((responseJson) => {
if(responseJson)
{
this.props.navigation.navigate('QrScan',{usertoken:responseJson.token});
}
else{
Alert.alert(responseJson);
}
}).catch((error) => {
console.error(error);
});
}
Please tell what's wrong with the "UserLogoutFunction"

React Native - fetch to setState returns the old value

I'm trying to update a row in database with API request Post when click in button (cancel or finish).
The value is update correctly in database but when i click button onPress={() => { settersApi('Finish'); gettersApi(); }} in gettersApi() console.log(estado) return the old value from hook "estado".
export default Home = ({navigation}) => {
const [estado, setEstado] = useState([]);
const gettersApi = async () => {
try {
let response = await fetch(
'http://api/getValues', {
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
},
}
);
let json = await response.json();
setEstado(json);
console.log(estado);
} catch (error) {
console.error(error);
}
};
useEffect(() => {
gettersApi();
}, []);
const settersApi = async (param) => {
try {
let response = await fetch(
'http://api/setValues', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
},
body: JSON.stringify({
id: estado.id,
estado: param,
})
}
);
let json = await response.json();
} catch (error) {
console.error(error);
}
};
const CButtons = () => {
return (
<View>
<View>
<Button
color='#ffc107'
title="CANCEL"
onPress={() => {
settersApi('Cancel');
gettersApi();
}}
/>
</View>
<View>
<Button
color='#28a745'
title="FINISH"
onPress={() => {
settersApi('Finish');
gettersApi();
}}
/>
</View>
</View>
);
};
return (
<View style={styles.body}>
<CButtons></CButtons>
</View>
);
};
The function from useState that you called setEtado is a async function. You wont see any changes right away after you change it.
Try to watch the variable state and see when it's updated by using useEffect
useEffect(() => {
console.log(estado);
}, [estado]);

Why can I not call on state in the render of a component after fetching data using fetch with React Native

Fairly new to React. Really new to react native. I know you should be able to reference state object in render method but when I try I get an error that is undefined. "Cant get variable of undefined" I want to set up a page that details each entry by id and the fetch method returns the details regarding each venue. I console this.state.data[0].venueName above and it logs out but when I try to reference it in the component it says its undefined.
class BreweryDetailScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
data: []
};
}
componentWillMount() {
this.getBrewDeetsHandler();
}
getBrewDeetsHandler = () => {fetch('api url', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
itemID: this.props.navigation.state.params.id
}),
}) .then(res => res.json())
.then(myJson => {
this.setState({
data: myJson
});
console.log(this.state.data[0].venueName)
})
.catch((error) => {
console.error(error);
});
};
render() {
return (
<Text>{this.state.data[0].venueName}</Text>
);
}
}
You should handle the loading phase!
you can try to define an isLoading: true state which will change to false when data have been loaded!
Also please do NOT make API request in componentWillMount() and use componentDidMount() instead!
look at this:
import React, { Component } from 'react';
import { View, Text, ActivityIndicator } from 'react-native';
class BreweryDetailScreen extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
data: []
};
}
componentDidMount() {
this.getBrewDeetsHandler();
}
getBrewDeetsHandler = () => {
fetch('api url', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
itemID: this.props.navigation.state.params.id
})
})
.then(res => res.json())
.then(myJson => {
this.setState({
isLoading: false,
data: myJson
});
console.log(this.state.data[0].venueName);
})
.catch(error => {
console.error(error);
});
};
render() {
if (this.state.isLoading) {
return (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}}
>
<ActivityIndicator size='large' color='red' />
</View>
);
} else {
return (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}}
>
<Text>{this.state.data[0].venueName}</Text>
</View>
);
}
}
}
export default BreweryDetailScreen;
Few good practices are,
Don't call API in componentWillMount,
componentWillMount() {
this.getBrewDeetsHandler();
}
To call API make use of componentDidMount,
componentDidMount() {
this.getBrewDeetsHandler();
}
API call is async, you won't be able to get data directly after API call because API call will take some time to execute and till that time your component will get render and you will get undefined error for your state.
You can make use of asyn/await for API call,
getBrewDeetsHandler = async () => {
await fetch('api url', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
itemID: this.props.navigation.state.params.id
}),
}) .then(res => res.json())
.then(myJson => {
this.setState({
data: myJson
}, ()=> console.log(this.state.data[0].venueName));//Callback in setState
})
.catch((error) => {
console.error(error);
});
};
After setting state, you won't be able to do console.log with new state value, because setState is also async, make use of callback in setState to console.log data, as I did above.
When you try to use state, do always check if state value exists,
<Text>{this.state.data && this.state.data[0].venueName}</Text>
because setState is an asynchronous operation and you are trying to access to state immediately after setState. please try this one.
this.setState({
data: myJson
}, () => { console.log(this.state.data[0].venueName); });
the second parameter of 'setState' method is a callback function which will be run after changing the state.

fetching values from server for multiselect picker react native

I tried fetching values from server for multi select picker component from the package https://github.com/toystars/react-native-multiple-select. But i get an error message: TypeError: null is not an object(evaluating this.state.LangKnown).
Please Kindly help.Thank u
My JSON values
{
"MFBasic": {
"SkinTones": "DARK,FAIR,VFAIR",
"Build": "SLIM,ATHLETIC,PLUMPY",
"Gender": "F,M,T",
"Genre": "ACTION,COMEDY,DRAMA",
"Languages": "ENG,HINDI,TAM",
"MediaModes": "ADS,MOVIES,SHORTFILMS",
"Tags": "BIKES,HOME,JEWELLARY"
},
"Result": "Successfully Loaded MF Basic Details",
"Code": 100
}
import React, {Component} from "react";
import { Text, View, StyleSheet, Picker, Alert } from "react-native";
import MultiSelect from "react-native-multiple-select";
export default class App extends React.Component {
state = {
LangPickerValueHolder: [],
LangKnown: []
}
componentDidMount () {
fetch('https://movieworld.sramaswamy.com/GetMFBasicDetails.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}).then(response => response.json())
.then(responseJson => {
let langString = responseJson.MFBasic.Languages;
let langArray = langString.split(',');
this.setState({
LangPickerValueHolder: langArray
});
}).catch(error => {
console.error(error);
});
}
render () {
return (
<View style={styles.itemContainer}>
{<MultiSelect
ref={(component) => { this.multiSelect = component; }}
onSelectedItemsChange={(value) =>
this.setState({ LangKnown: value })
}
selectedItems={this.state.LangKnown}
onChangeInput={ (text) => console.log(text)}
displayKey = ''name
submitButtonText="Submit">
{this.state.LangPickerValueHolder.map((item, key) => (
<MultiSelect.Item item = {item} uniqueKey = {key}/>
))}
</MultiSelect>}
</View>
);
}
}
You've made a good attempt at how to set up the MultiSelect however there are a couple of issues that need to be resolved.
If you look at the dependency the data that should be passed to it should be an array of objects. The example gives the object as { id: '92iijs7yta', name: 'Ondo' } We can easily transform your data from an array of strings into an array of objects that match the example.
let LangPickerValueHolder = langArray.map((name, id) => { return { name, id }; });
Using a map we can convert the array.
This would make your componentDidMount look like the following:
componentDidMount () {
fetch('https://movieworld.sramaswamy.com/GetMFBasicDetails.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}).then(response => response.json())
.then(responseJson => {
let langString = responseJson.MFBasic.Languages;
let langArray = langString.split(',');
let LangPickerValueHolder = langArray.map((name, id) => { return { name, id }; }); // <- here we had the mapping function
this.setState({ LangPickerValueHolder }); // <- save the new array of objects into the state
console.log(langArray);
}).catch(error => {
console.error(error);
});
}
Setting up the MultiSelect component requires a few more changes.
Firstly there is no MultiSelect.Item so the map that you are using to populate the MultiSelect won't work. Instead you need to use the items prop to set the items. Next you need to tell the MultiSelect component the correct uniqueKey prop (which in our case will be id) and set the displayKey correctly.
Here is what your render could look like.
render () {
return (
<View style={styles.container}>
<MultiSelect
ref={(component) => { this.multiSelect = component; }}
onSelectedItemsChange={(value) =>
this.setState({ LangKnown: value })
}
uniqueKey="id"
items={this.state.LangPickerValueHolder}
selectedItems={this.state.LangKnown}
onChangeInput={ (text) => console.log(text)}
displayKey = 'name'
submitButtonText="Submit" />
</View>
);
}
Here is it put together in a snack: https://snack.expo.io/#andypandy/multiselect-with-data-from-api
Here is the code from the snack:
import React from 'react';
import { View, StyleSheet } from 'react-native';
import MultiSelect from 'react-native-multiple-select';
export default class App extends React.Component {
// declaring state like this is absolutely fine, it doesn't need to be in a constructor
state = {
LangPickerValueHolder: [],
LangKnown: []
}
componentDidMount () {
fetch('https://movieworld.sramaswamy.com/GetMFBasicDetails.php', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}).then(response => response.json())
.then(responseJson => {
let langString = responseJson.MFBasic.Languages;
let langArray = langString.split(',');
let LangPickerValueHolder = langArray.map((name, id) => { return { name, id }; });
this.setState({
LangPickerValueHolder
});
console.log(langArray);
}).catch(error => {
console.error(error);
});
}
render () {
return (
<View style={styles.container}>
<MultiSelect
ref={(component) => { this.multiSelect = component; }}
onSelectedItemsChange={(value) =>
this.setState({ LangKnown: value })
}
uniqueKey="id" // <- set the value for the uniqueKey
items={this.state.LangPickerValueHolder} // <- set the items you wish to show
selectedItems={this.state.LangKnown}
onChangeInput={ (text) => console.log(text)}
displayKey = 'name' . // <- fix typo here
submitButtonText="Submit" />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: 'white',
padding: 8
}
});

react-native Can't display value got in my fetch

I can't display the values ​​retrieved from my fetch to my
This is my code, but I get 'null is not an object' :
import React, {Component} from 'react';
import { StyleSheet, Image, Text, View, TextInput, StatusBar, Button,
AppRegistry, TouchableHighlight, TouchableOpacity } from 'react-native';
import AndroidBackButton from 'react-native-android-back-button'
import { StackNavigator } from 'react-navigation'
export default class ComponenFive extends React.Component {
getInfos(){
fetch('http://172.16.101.183:3000/users', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
requestType: 'infosCompte'
})
})
.then((response) => response.json())
.then((res) => {
this.setState({username: res.username, nom: res.nom, prenom: res.prenom, lieu: res.lieu, batiment: res.batiment, bureau: res.bureau});
})
.done();
}
render() {
{this.getInfos}
return (
<View style={{backgroundColor: 'white', flex: 1}}>
<Text>Identifiant : {this.state.username}</Text>
</View>
)
}
}
Do you have any idea to help me ?
using fetch you are getting more than just the data on json.
try this example
fetch('http://172.16.101.183:3000/users', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
requestType: 'infosCompte'
})
})
.then(response => response.json().then(json => ({ json, response })))
.then(({ json, response }) => {
if (!response.ok) {
return Promise.reject(json);
}
return json;
})
.then((res) => {
this.setState({username: res.username, nom: res.nom, prenom: res.prenom, lieu: res.lieu, batiment: res.batiment, bureau: res.bureau});
})
.done();
UPDATE:
Sorry just seen your code and is not correct. Using {this.getInfos} on render() is wrong. getInfo is just a function. You dont return anything. If you want to call this function as it is use componentWillMount and set the state on constructor
constructor(props) {
super(props);
this.state = {username: '', nom: ''};
}
componentWillMount() {
this.getInfos()
}
res already json. pull the data directly from the res.
console.log(res);
let resData = JSON.parse(res._bodyText);
this.setState({username: resData.username, nom: resData.nom, .....})