Promise is not resolving in useEffect hook

Viewed 67

I am getting response from api which i need to render.

following is the sample response (relevant fields only):

 [
    {
        ...other fields,
        "latitude": "33.5682166",
        "longitude": "73.207334",
       
       
    },
    {
       ...otherfields,
        "latitude": "33.5602917176197",
        "longitude": "73.22683267327477",
      
    }
]

i need to render the following component using above response (relevant code only):

import { getReverseGeocodedLocation } from "../../../services/getLocation";
import { useEffect, useState,memo } from "react";



 type Props = {
  category_id: number;
  id: number;
  title: string;
  price: string;
  lat: string;
  lng: string;
  category: string;
  source: ImageSourcePropType;
};

const RecentPost: React.FC<Props> = (props) => {

...otherCode,
 
  useEffect(() => {
    (async () => {
      //This promise below is not resolving for first few entries of api res
      //For later entries in the array from api res, it resolves.
      // if only single entry is sent from api then it resolves successfully
      

      const address = await getReverseGeocodedLocation(
        parseFloat(props.lat),
        parseFloat(props.lng)
      );

      address.description && setDescription(address.description);
    })();
  }, []);

  return (
        ...allTheComponentsBasedOnApiResponse,
  );
};

export default memo(RecentPost, () => true);

Following is the parent component which renders above component:

import { useEffect, useState } from "react";
import RecentPost from "./RecentPost";

const RecentPosts: React.FC = () => {
  const [recent_posts, set_recent_posts] = useState<rent_post_brief[]>([]);
  const [posts_loading, set_posts_loading] = useState(true);
  const city_name = useAppSelector((state) => state.location.city_name);

...otherStuff,

  useEffect(() => {
    (async () => {
      try {
        set_posts_loading(true);

        const res = await rentApi.get<rent_post_brief[]>(`/rent/recent-posts`, {
          params: {
            city: city_name === "All cities" ? undefined : city_name,
            filter,
          },
        });

        set_recent_posts(res.data);
      } finally {
        set_posts_loading(false);
      }
    })();
  }, [city_name, filter]);

  return (
    <>
      ...otherStuff,
        {posts_loading ? (
          <LoadingText />
        ) : recent_posts.length > 0 ? (
          recent_posts.map((item) => {
            return (
              <RecentPost
                id={item.id}
                category_id={item.category.id}
                key={`${item.id}`}
                source={{ uri: item.uploaded_media[0].file }}
                title={item.title}
                price={item.price}
                lat={item.latitude}
                lng={item.longitude}
                category={item.category.title}
              />
            );
          })
        ) : (
          <NoPosts />
        )}
      </View>
     ...otherStuff,
    </>
  );
};

export const NoPosts: React.FC = () => (
  <Animated.Text style={styles.no_posts} entering={FadeIn} exiting={FadeOut}>
    No posts for current settings, kindly either change city or change filter.
  </Animated.Text>
);

export default RecentPosts;

Following is the function which returns the promise:

import * as Location from "expo-location";

/**
 * Takes location coordiantes and returns string location
 * @param latitude
 * @param longitude
 * @returns Promise resolving to string location
 */
export const getReverseGeocodedLocation = async (
  latitude: number,
  longitude: number
) => {
  const reverse_geocoded_results = await Location.reverseGeocodeAsync({
    latitude,
    longitude,
  });

  const result = reverse_geocoded_results[0];

  const { city, district } = result;

  return { city, description: district };
};
1 Answers

Finally managed to isolate the problem.

It is due to the async function of expo-location i.e reverseGeocodeAsync that i am using. It is written in the docs (https://docs.expo.dev/versions/latest/sdk/location/#locationreversegeocodeasynclocation-options):

"Note: Geocoding is resource consuming and has to be used reasonably. Creating too many requests at a time can result in an error, so they have to be managed properly. It's also discouraged to use geocoding while the app is in the background and its results won't be shown to the user immediately."

I was sending multiple requests using this function which was creating the problem. Decided to change my approach after reading this.

Related