I am trying to get data from a endpoint and then output this data, I can successfully get my data fetched and display it immediately using
fetch(strURL)
.then(res => res.json())
.then((result) => {
console.log("grabed data " JSON.stringify(result));
But whenever I try to set the data to my State variable response
it fails to do so resulting in an undefined variable. I am really confused why this is occurring as I have another screen that fetches a the same endpoint but it doesn't seem to save to the state variable.
This is the data which is returned:
[{"act_id":"1","act_name":"A bush adventure trail ride in the blue mountains","cat_sub_category":"Free riding","bus_name":"Ditch the road"},{"act_id":"2","act_name":"Paddock riding in the ditch","cat_sub_category":"stable riding","bus_name":"Hallam horses"}]
This is the working screen which fetches the data above
function ActivityDemo(props) {
let [isLoading, setIsLoading] = useState(true);
let [error,setError] = useState();
let [response,setResponse] = useState();
useEffect(() =>{
console.log("fetch activities");
fetch("https://domain/api/activities.php")
.then(res => res.json())
.then((result) => {
console.log("grabed data " result);
setIsLoading(false);
setResponse(result);
},
(error) => {
setIsLoading(true);
setError(error);
console.error("error ")
})
}, []);
//What renders
const renderItem = ({item}) => (
<ActivityWidget item={item} ></ActivityWidget>
);
//determines what is displayed
const getContent = (navigation) => {
if (isLoading == true){
return <ActivityIndicator size="large"></ActivityIndicator>
}
if(error == true){
return <Text>{error}</Text>
}
if(isLoading ==false){
console.log(response);
return (
<FlatList
data={response}
renderItem={renderItem}
keyExtractor={item => item.act_id}
/>
);
}
}
return(
<View style={[ContainerStyle.Center]}>
{getContent()}
</View>
);
}
This snippet is from the screen which doesn't work
function ActivityDetails({route},props) {
//get the Route variables
const {actId} = route.params;
let [isLoading, setIsLoading] = useState(true);
let [error, setError] = useState();
let [response, setResponse] = useState();
let strURL = "https://domain/api/detailedActivity.php?actId=" actId;
useEffect(() =>{
console.log("fetch detailed data!");
console.log(strURL);
fetch("https://domain/api/activities.php")
.then(res => res.json())
.then((result) => {
console.log("grabed data " JSON.stringify(result));
setIsLoading(false);
setResponse(result);
},
(error) => {
setIsLoading(true);
setError(error);
console.error("error " error)
})
}, []);
//determines what is displayed
const getContent = () => {
if (isLoading == true){
return <ActivityIndicator size="large"></ActivityIndicator>;
}
if(isLoading == false){
console.log("Load response Data " response);
return(
<View style={[ContainerStyle.Container]} >
<Text>{"Name: " response[0].act_name}</Text>
<Text>{"Description: " response[0].act_description}</Text>
<Text>{"Bussiness: " response[0].act_name}</Text>
<Text>{"Category: " response[0].act_name}</Text>
</View>
);
}
if (error == true){
return <Text>{error}</Text>
}
}
return(
<View style={[ContainerStyle.Center]}>
{getContent()}
</View>
);
}
This is the console logs
LOG fetch activities
LOG grabed data [object Object],[object Object]
LOG undefined
LOG [{"act_id": "1", "act_name": "A bush adventure trail ride in the blue mountains", "bus_name": "Ditch the road", "cat_sub_category": "Free riding"}, {"act_id": "2", "act_name": "Paddock riding in the ditch", "bus_name": "Hallam horses", "cat_sub_category": "stable riding"}]
LOG fetch detailed data!
LOG https://domain/api/detailedActivity.php?actId=2
LOG grabed data [{"act_id":"1","act_name":"A bush adventure trail ride in the blue mountains","cat_sub_category":"Free riding","bus_name":"Ditch the road"},{"act_id":"2","act_name":"Paddock riding in the ditch","cat_sub_category":"stable riding","bus_name":"Hallam horses"}]
LOG Load response Data undefined
LOG Load response Data undefined
I'm not sure why this is not working If someone could tell me what I am doing wrong? Is it to do with the way I am setting state?
Thank you, Andrew
edit: I've hidden the endpoints domain
CodePudding user response:
Try this way. Create response state like below.
const [response,setResponse] = useState([]);
then assign value like below
setResponse([...result]);
CodePudding user response:
I have fixed the issue by converting my functions to classes and formatting it with a ComponentDidMount.
class ActivityInfo extends Component {
state = { response : [], isLoading : true};
componentDidMount(){
const {navigation, route}=this.props
const { actId } = route.params;
console.log(actId);
const res = fetch("https://domain/api/detailedActivity.php?actId=" actId)
.then(res => res.json())
.then((result) => {
console.log("grabbed data " result);
this.setState({isLoading:false,response:result});
},
(error) => {
setIsLoading(true);
setError(error);
console.error("error ")
})
console.log(this.state.response)
}
render(){
if(this.state.isLoading == true){
return(<ActivityIndicator style={{alignSelf:"center"}} size="large"></ActivityIndicator>)
}
else{
return(
<View style={[ContainerStyle.Container]} >
<Text>{"Name: " this.state.response[0].act_name}</Text>
<Text>{"Description: " this.state.response[0].act_description}</Text>
<Text>{"Bussiness: " this.state.response[0].bus_name}</Text>
<Text>{"Category: " this.state.response[0].act_id}</Text>
</View>
);
}
}
}