Home > Mobile >  i need some help getting data from an api call
i need some help getting data from an api call

Time:01-01

im sure im just doing something stupid, but i cant figure out what im doing wrong.

when the user fills out their state and city and hits submit, that should run a fetch request for lat and lon values. then that needs to be fed into another api that gives the weather based on lat and lon. im using react.js

import {React, useState} from 'react'

export default function Home () {
    // // GeoApify gets Lat/Long
    // const geo = fetch(`https://api.geoapify.com/v1/geocode/search?city=${details.city}&state=${details.state}&format=json&apiKey=27a84d7b0c1b4d52b41acc3e82bbe239`)
    // // OpenWeatherApi One Call API 3.0 gets the weather of the Lat/Long
    // const weather = fetch(`https://api.openweathermap.org/data/3.0/onecall?lat=${coord.lat}&lon=${coord.lon}&appid=544ce8f74a895e6f7bd6425293b01b47`)

    const [coord, setCoord] = useState({lat:'', lon:''})
    const [details, setDetails] = useState({city:'', state:''})

    const fetch = (req, res) => {
        fetch(`https://api.geoapify.com/v1/geocode/search?city=${details.city}&state=${details.state}&format=json&apiKey=27a84d7b0c1b4d52b41acc3e82bbe239`)
        .then((res) => res.json())
        .then(fetch(`https://api.openweathermap.org/data/3.0/onecall?lat=${res.results.lat}&lon=${res.results.lon}&appid=544ce8f74a895e6f7bd6425293b01b47`))
        .then((res) => res.json())
        .then(weather.push(res))
    }
    const weather = []
    return(
        <div>
            <h4>Home</h4>
            <form id='form'>
                <p><label htmlFor='city'>City: </label>
                <input placeholder='City' type='text' name='city' onChange={e => setDetails({...details, city:e.target.value}, console.log(details))} value={details.city} /></p>
                <p><label htmlFor='state'>State: </label>
                <input placeholder='State' type='text' name='state' onChange={e => setDetails({...details, state:e.target.value}, console.log(details))} value={details.state} /> </p>
                <p><input type='submit' value='Submit' onSubmit={fetch()} /></p>
            </form>
        </div>
    )
}

i keep getting an error that says "Uncaught RangeError: Maximum call stack size exceeded". why does it seem to be looping? it also seems to be calling the "fetch" function before the form is submitted.

for refernce this is what a call from the lat/lon api looks like

{
"results": [
{
"datasource": {},
"country": "United States",
"country_code": "us",
"state": "Georgia",
"county": "Gwinnett County",
"city": "Snellville",
"town": "Snellville",
"lon": -84.0199108,
"lat": 33.857328,
"state_code": "GA",
"distance": 0,
"formatted": "Snellville, GA, United States of America",
"address_line1": "Snellville, GA",
"address_line2": "United States of America",
"category": "administrative",
"timezone": {
"name": "America/New_York",
"offset_STD": "-05:00",
"offset_STD_seconds": -18000,
"offset_DST": "-04:00",
"offset_DST_seconds": -14400,
"abbreviation_STD": "EST",
"abbreviation_DST": "EDT"
},
"result_type": "city",
"rank": {
"importance": 0.5276231202788444,
"popularity": 3.3564440571456937,
"confidence": 1,
"confidence_city_level": 1,
"match_type": "full_match"
},
"place_id": "5195b5f237460155c059f9f884ecbced4040f00101f90127d3010000000000c00208",
"bbox": {
"lon1": -84.042913,
"lat1": 33.818392,
"lon2": -83.950932,
"lat2": 33.89217
}
}
],
"query": {}
}

i just need the lat/lon from it

CodePudding user response:

import { React, useState } from "react";

export default function Home() {
  const [coord, setCoord] = useState({ lat: "", lon: "" });
  const [details, setDetails] = useState({ city: "", state: "" });

  const fetch = (req, res) => {
    fetch(
      `https://api.geoapify.com/v1/geocode/search?city=${details.city}&state=${details.state}&format=json&apiKey=27a84d7b0c1b4d52b41acc3e82bbe239`
    )
      .then((res) => res.json())
      .then(
        fetch(
          `https://api.openweathermap.org/data/3.0/onecall?lat=${res.results.lat}&lon=${res.results.lon}&appid=544ce8f74a895e6f7bd6425293b01b47`
        )
      )
      .then((res) => res.json())
      .then((data) => {
        const { lat, lon } = data.results[0];
        setCoord({ lat, lon });
      });
  };
  return (
    <div>
      <h4>Home</h4>
      <form id="form">
        <p>
          <label htmlFor="city">City: </label>
          <input
            placeholder="City"
            type="text"
            name="city"
            onChange={(e) =>
              setDetails(
                { ...details, city: e.target.value },
                console.log(details)
              )
            }
            value={details.city}
          />
        </p>
        <p>
          <label htmlFor="state">State: </label>
          <input
            placeholder="State"
            type="text"
            name="state"
            onChange={(e) =>
              setDetails(
                { ...details, state: e.target.value },
                console.log(details)
              )
            }
            value={details.state}
          />{" "}
        </p>
        <p>
          <input type="submit" value="Submit" onSubmit={fetch()} />
        </p>
      </form>
    </div>
  );
}

CodePudding user response:

Well... Frist of all, your code form is a little bit messy, you should declare an async function to handle the submit request. Then you should have something like this:

// I renamed fetch to fetchFunction because fetch is an already function in node18 or browser
const fetchFunction = async () => {
    // this is your first request and from this u shoul parse your data
    try {
        const response = await(await fetch(`https://api.geoapify.com/v1/geocode/search?city=${details.city}&state=${details.state}&format=json&apiKey=27a84d7b0c1b4d52b41acc3e82bbe239`)).json();

        // and here you should do your second fetch in the same maner
    } catch (error) {
        console.log(error)
    }
}

That error is popping out because you have a memory leak here:

<input type='submit' value='Submit' onSubmit={fetch()} />

and the right form for this is (or "onSubmit={fetchFunction}" if you take my approach):

<input type='submit' value='Submit' onSubmit={fetch} />
  • Related