Home > database >  State is not updating with my data fetched from an API
State is not updating with my data fetched from an API

Time:11-28

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>
            );
        }
    }
}
  • Related