Home > Net >  async await promise rejection in react hook
async await promise rejection in react hook

Time:09-11

I think I am missunderstanding how the async await is working, especially with a function from another file. So I want to get an adress from longitude and latitude using an axios call on an API

import { getAddressFromLongLat } from "../hooks/queries-hook";
import React, { useEffect, useState } from "react";

const Component = (props) => {
  const [address, setAddress] = useState(null);
  useEffect(() => {
    const fetchFromLongLat = async () => {
      if (props.coords) {
        const response = await getAddressFromLongLat(props.coords);
        console.log("response from nominatim "   JSON.stringify(response, null, 4));
        setAddress(response);
      }
    };
    fetchFromLongLat();
  }, []);

  return <></>;
};

then into queries-hook.js

import axios from "axios";

export const getAddressFromLongLat = async (coords) => {
  const URL = "http://nominatim.openstreetmap.org/reverse";
  const response = await axios.get(URL, {
    params: {
      format: "json",
      lat: coords.lat,
      lon: coords.long
    },
    headers: {
      "Content-Type": "application/json; charset=UTF-8"
    }
  });
  return {
    street: response.address.road   " "   response.address.house_number,
    cp: response.address.postcode,
    city: response.address.town,
    country: response.address.country_code.toUpperCase()
  };
};

can someone explain me how I should write correctly the code with those async await to not have the error:

Possible Unhandled Promise Rejection (id: 0): TypeError: undefined is not an object (evaluating 'response.address.road')

CodePudding user response:

Issue is due to response does not contains address property and all the rest. But response.data do.

You had to add a console.log(response); before return to figure that out. The output for { "lat": 50.806002951249546, "long": 4.410705976188183 } will be this:

{
  "data": {
    "place_id": 113461740,
    "licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
    "osm_type": "way",
    "osm_id": 30994925,
    "lat": "50.8066154",
    "lon": "4.410838323013642",
    "display_name": "Parc sportif des Trois Tilleuls, Avenue Léopold Wiener - Léopold Wienerlaan, Le Triangle - De Driehoek, Ватермаль-Буафор, Брюссельский столичный регион, 1170, Бельгия",
    "address": {
      "leisure": "Parc sportif des Trois Tilleuls",
      "road": "Avenue Léopold Wiener - Léopold Wienerlaan",
      "neighbourhood": "Le Triangle - De Driehoek",
      "town": "Ватермаль-Буафор",
      "county": "Брюссельский столичный регион",
      "region": "Брюссельский столичный регион",
      "ISO3166-2-lvl4": "BE-BRU",
      "postcode": "1170",
      "country": "Бельгия",
      "country_code": "be"
    },
    "boundingbox": [
      "50.8042107",
      "50.80902",
      "4.4079878",
      "4.4130556"
    ]
  },
  "status": 200,
  "statusText": "",
  ...
  (cutted)
} 

So fixed function:

const getAddressFromLongLat = async (coords) => {
  // switched to HTTPS here also
  const URL = "https://nominatim.openstreetmap.org/reverse";
  const response = await axios.get(URL, {
    params: {
      format: "json",
      lat: coords.lat,
      lon: coords.long
    },
    headers: {
      "Content-Type": "application/json; charset=UTF-8"
    }
  });
  const { data } = response; // equal to const data = response.data
  return {
    street: data.address.road   " "   data.address.house_number,
    cp: data.address.postcode,
    city: data.address.town,
    country: data.address.country_code.toUpperCase()
  };
};

CodePudding user response:

import axios from 'axios';
import React from 'react'
import { useEffect } from 'react';
import { useState } from 'react';

const Try = () => {

    const [address, setAddress] = useState(null);

    const getAddressFromLongLat = async () => {
        const URL = "http://nominatim.openstreetmap.org/reverse";
        const response = await axios.get(URL, {
            params: {
                format: "json",
                lat: 36.884804,
                lon: 30.704044
            },
            headers: {
                "Content-Type": "application/json; charset=UTF-8"
            }
        });
        const { data } = response; **// There is your mistake.**
        return {

            street: data.address.road   " "   data.address.house_number,
            cp: data.address.postcode,
            city: data.address.town,
            country: data.address.country_code.toUpperCase()
        };
    };

    useEffect(() => {
        const fetchFromLongLat = async () => {
            if (1 === 1) {
                const response = await getAddressFromLongLat();
                console.log("response from nominatim "   JSON.stringify(response, null, 4));
                setAddress(response);
            }
        };
        fetchFromLongLat();
    }, []);

    console.log(address)
    return (
        <div>try</div>
    )
}

export default Try
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.27.2/axios.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

CodePudding user response:

I'm not sure, but may be you don't need use async...await in second function. This is like tako inside tako. But you need just two tako in one tako bell.

  • Related