Home > OS >  Rest API React and AXIOS in functional component
Rest API React and AXIOS in functional component

Time:11-29

I need to parse Rest API resposnes with JSON. But when I use AXIOS in functional compoment it returns first empty array and then exact api response.data / after render. So return functions returns empty array but in the fact the data is there but after rendering

The api response

{
"eventId": "3c6a12e3-ac96-4f9d-9d26-7c7a6c730198",
"organizerId": "23a41cd1-e60e-41ff-b5d3-13815ed9b3a9",
"eventDate": "2021-11-28T14:14:16.191167",
"eventPlayerLimit": 10,
"eventFee": 0.0,
"playerSubscriptions": [
{
"subscriptionId": "2616720f-7106-429e-89f6-97be51dfbaf6",
"subscriptionPaymentDone": "true",
"subscriptionDate": "2021-11-28T14:14:16.217146",
"subscriptionApproved": "true",
"eventTitle": "Title",
"eventDate": "2021-11-28T14:14:16.191167",
"playerId": "a04d3ca2-af3d-4655-9eaf-6a892efe2dab",
"playerEmail": "[email protected]"
}
],
"title": "Title"
}

And the component body

import React, {Component, useEffect, useState} from "react";
import {Card, Button, Table} from "react-bootstrap";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCoffee } from '@fortawesome/free-solid-svg-icons'
import axios from "axios";
import {useParams} from "react-router-dom";

function EventsDetails () {
  const [eventDetails, setEventDetails] = useState([])
    let {id} = useParams();
    function getEvents() {
        axios.get("http://localhost:8080/api/events/" id)
            .then(response => response.data)
            .then((data) => {
                setEventDetails(data)
            });
    }
    useEffect(()=>{
        getEvents();
    },[])
    console.log(id);
    console.log(eventDetails);
        return (
            <Card className={"border border-dark bg-dark text-white"}>
                <Card.Header><FontAwesomeIcon icon={faCoffee} /> Events</Card.Header>
                <Card.Body>
                    <Table bordered hover striped variant="dark">
                        <thead>
                        <tr align="center">
                            <th>Event Date</th>
                            <th>Event title</th>
                            <th>Localization</th>
                            <th>Payment Fee</th>
                            <th>Subscribed users</th>
                            <th>Actions</th>
                        </tr>
                        </thead>
                        <tbody>
                        {eventDetails.length === 0 ?
                            <tr align="center">
                                <td colSpan="6">No events available</td>
                            </tr> :
                            <tr align="center">
                            <td colSpan="6">{eventDetails.length}</td>
                            </tr>
                        }
                        </tbody>
                    </Table>
                </Card.Body>
            </Card>
)
}export default EventsDetails

Console log Console LOG

CodePudding user response:

That is the expected behavior. Your first console.log is being executed before the state update. The function is not returning an empty array, you're seeing the default state from const [eventDetails, setEventDetails] = useState([]) being logged.

CodePudding user response:

Initially on the page load... you dont have data because API takes some moment before it respond with data and meanwhile your component already rendered with empty array i.e no data...

at some moment later the API comes back with data and update the state but you've already seen a component without required data...

So a way around it is

You put a component/content/loader to be shown while you're waiting for API to give you data to be shown... and when that data comes you take back the loader component and show that data from API

With codes it could be something as below

import React, {Component, useEffect, useState} from "react";
import {Card, Button, Table} from "react-bootstrap";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCoffee } from '@fortawesome/free-solid-svg-icons'
import axios from "axios";
import {useParams} from "react-router-dom";

function EventsDetails () {
  const [eventDetails, setEventDetails] = useState([])
  const [isLoading, setIsLoading] = useState(false);
    let {id} = useParams();
    function getEvents() {
        setIsLoading(true);
        axios.get("http://localhost:8080/api/events/" id)
            .then(response => response.data)
            .then((data) => {
                setEventDetails(data)
                setIsLoading(false);
            });
    }
    useEffect(()=>{
        getEvents();
    },[])
    
    ....//removed for brevity

    return <>{isLoading ? <DisplayLoader /> : <DisplayData />}</>

CodePudding user response:

Thanks guys. Sometimes I have undefined errors. Now I understand why. My function is called on every render. So I added Loader

  • Related