0

I am new to react and I try to get data from the backend and view that data in the frontend. To do that I tried this code:

function VProfile() {

    const buyerId=(localStorage.getItem("userId"));
    console.log(buyerId);

    const [buyerDetails, setBuyerDetails] = useState({});

    useEffect(() => {
        axios
            .get(`/getBuyerDetails`)
            .then((response) => setBuyerDetails(response.data.existingBuyers))
            .catch((err) => console.error(err));
    }, []);

    console.log(buyerDetails);

    const oneBuyer = buyerDetails?.find(oneBuyer => oneBuyer.buyerId === buyerId);
    console.log(oneBuyer);
}

When I call the API I get a length 3 array of objects. This is an image of the data.

Results of API call

Then I try to find the data of a specific buyer using the find function. To do that I use this const oneBuyer = buyerDetails?.find(oneBuyer => oneBuyer.buyerId === buyerId) code. But then I got an error that says TypeError: buyerDetails.find is not a function. How do I silve this problem?

Thank You!

3 Answers 3

2

You initialize the state with an object ({}):

const [buyerDetails, setBuyerDetails] = useState({});

Objects don't have .find, only arrays do.

You might want to initialize it to an empty array ([]), or undefined to more clearly signal the case that the data is not yet loaded.

Sign up to request clarification or add additional context in comments.

Comments

1

You call setBuyerDetails asynchronously, so at the moment when you log them, the data hasn't arrived, due to console.log you are being "deceived" to believe the data is there. From docs:

Please be warned that if you log objects in the latest versions of Chrome and Firefox what you get logged on the console is a reference to the object, which is not necessarily the 'value' of the object at the moment in time you call console.log(), but it is the value of the object at the moment you open the console.

To avoid that error you can initialize that variable with empty array initially:

const [buyerDetails, setBuyerDetails] = useState([]);

Comments

0

Do it something like that and initialize with an array and you are using async operations so please add the loading flag

function VProfile() {
    const buyerId=(localStorage.getItem("userId"));
    console.log(buyerId);

    const [buyerDetails, setBuyerDetails] = useState([]);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        axios
            .get(`/getBuyerDetails`)
            .then((response) => {
                setBuyerDetails(response.data.existingBuyers));
                setLoading(false);
            })
            .catch((err) => console.error(err));
    }, []);

    console.log(buyerDetails);

    if (loading) return <p>loading....</p>

    const oneBuyer = buyerDetails?.find(oneBuyer => oneBuyer.buyerId === buyerId);
    console.log(oneBuyer);
}

4 Comments

There's no need to use a separate state atom for the "loading" state when you can use e.g. undefined (or any other "out-of-band" value) for the data to be loaded to signal the same. :)
Yes, you are right but this solution will works perfect when there are multiple calls
It's still likely not worth it to keep it a state atom - you could just as well do const loading = (data1 === undefined || data2 === undefined);...
Yes that is also an option and its valid because setState will create new rerender

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.