Ad

Async Function Returning Empty Array, And Then The Desired Data - Causing App To Crash

- 1 answer

In my react project, I have a function getDetails that takes in the data retrieved from a database call (filteredVenue), and then console logs that data. This function exists inside a component called MidSection.js. When this component is rendered and getDetails is invoked, the following is logged to the brower:

MidSection.js:9 [ ]
MidSection.js:9 [{…}]

The problem is this - initially, an empty array is being returned which means that is I try to access the data inside filteredReviews, I get an undefined error.

As an example the following code

  const extractRatings =   () => {
    const foodRatings = []
    filteredVenue[0].reviews.map((rating) => {
     foodRatings.push(rating.ratingFood)
    })
    return {foodRatings}
  }

  const {foodRatings} = extractRatings()

....yields the following error

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'reviews')

...and this is happening because the function is initially recieving an empty array. ANy ideas on how to solve this?

Here's the rest of the code:

MidSection.js

import { useEffect,useState } from 'react'
import { convertToStars } from "../../helperFunctions";


const MidSection = ({ filteredVenue }) => {

const getDetails = async () => {
  const data =  await filteredVenue
  console.log(data)
}

getDetails()


  return (
    <div className="venue-page-mid">
      {filteredVenue.map((venue) => {
        return (
          <>
            <div className="venue-page-section left">
              <h2>Ratings and reviews</h2>
              <p>
                {venue.averageRating}
                {` `}
                {convertToStars(venue.averageRating)}
                {`  `}({`${venue.reviews.length} reviews`})
              </p>
              <div className="ratings">
                <h3>Ratings</h3>
              </div>
            </div>
            <div className="venue-page-section mid">
              <h2>Details</h2>
              <div className="details-container">
                <div className="details-item">
                  <h3>Cuisines</h3>
                  <p>Cafe</p>
                </div>
                <div className="details-item">
                  <h3>Special diets</h3>
                  <p>Vegetarian friendly, vegan options, gluten-free options</p>
                </div>
                <div className="details-item">
                  <h3>Meals</h3>
                  <p>Breakfast, Brunch, Lunch, After hours</p>
                </div>
              </div>
            </div>
          </>
        );
      })}
    </div>
  );
};

export default MidSection;

The call to my firebase firestore database (in useVenue.js):

import { useState,useEffect } from 'react'
import { firebase } from './firebaseConfig'

export  function useVenues (){
  const [venues, setVenues] = useState([]);
  useEffect(() => {
    const venueArray = [];
    const getAllVenues =  () => {
       firebase
        .firestore()
        .collection("venues")
        .get()
        .then((snapshot) => {
          snapshot.forEach((venue) => {
            venueArray.push(venue);
          });
          setVenues(venueArray);
        });
    };
    getAllVenues();
  }, []);

  const [...venueData] = venues.map((venue) => {
    
    const { 
      name, 
      photoUrl, 
      averageRating, 
      numRatings, 
      type,
      address,
      phone,
      website,
      reviews } = venue.data();

    return ({
      name: name,
      photoUrl: photoUrl,
      averageRating: averageRating,
      numRatings: numRatings,
      type: type,
      id: venue.id,
      reviews:reviews,
      address:address,
      phone:phone,
      website:website
    })
  });
  return {venueData}
};

Ad

Answer

just add a check wherever you feel , it is undefined or null.

 const extractRatings =   () => {
    const foodRatings = []
    
  !!filteredVenue && filteredVenue.length>0 && filteredVenue[0].reviews.map((rating) => {
     foodRatings.push(rating.ratingFood)
    })
    return {foodRatings}
  }

  const {foodRatings} = extractRatings()

This must solve your issue .

Ad
source: stackoverflow.com
Ad