Home > Mobile >  How can I fetch the correct info from an API?
How can I fetch the correct info from an API?

Time:08-15

I'm building a weather forecast website with TypeScript and React, but I'm having some trouble to fetch just the cityName.id that I clicked from the first displayed list. When I search a specific city, the API provides a list of cities that contain the name I typed. Please find below what I've done so far:

import { useState, useEffect, ChangeEventHandler, FormEventHandler } from "react"
import { ApiAdvisorVariables } from "../../../variables"

export function ApiAdvisor() {

    const [cityName, setCityName] = useState<string>('')
    const [value, setValue] = useState<string>('')
    const [cityInfo, setCityInfo]: any = useState<{} | null>([])
    const [cityWeather, setCityWeather]: any = useState<{} | null>([])
    const [cityId, setCityId] = useState<any>(3477)

    const handleChange: ChangeEventHandler<HTMLInputElement> = (event: any): void => {
        setValue(event.target.value)
    }

    const handleSubmit: FormEventHandler<HTMLFormElement> = (event: any): void => {
        event.preventDefault()
        setCityName(value)
    }

    const handleClick: FormEventHandler<HTMLFormElement> = (): void => {
       cityInfo.map((index: any) => {
        setCityId(index.id)
        console.log(index.id)
       })
        
    }

    async function getCityId(cityName: string): Promise<any> {

        const response = await fetch(`http://apiadvisor.climatempo.com.br/api/v1/locale/city?name=${cityName}&token=${ApiAdvisorVariables.token}`)
        const data = await response.json()
        console.log(data)
        return data
    }

    async function getCurrentWeather(cityId: string): Promise<any> {
      
        const response = await fetch(`http://apiadvisor.climatempo.com.br/api/v1/weather/locale/${cityId}/current?token=${ApiAdvisorVariables.token}`)
        const data = await response.json()
        console.log(data)
        return data
    }

    useEffect(() => {
        async function fetchData() {
            const idInfo = await getCityId(cityName)
            const weatherInfo = await getCurrentWeather(cityId)
            setCityInfo(idInfo)
            setCityWeather(weatherInfo)          
        }
        fetchData()

    }, [cityName, cityId])

    return (
        <section>

            <div className="search-container">
                <form onClick={handleSubmit}>
                    <input
                        onChange={handleChange}
                        placeholder="Digite o nome da cidade"
                    />
                    <button>Search</button>
                </form>
            </div>

                <div className="weather-info-container">
                    {cityInfo ? cityInfo.map((index: any, key: string) => {
                        return (
                            <form key={key} onClick={handleClick}>
                                <h2> {index.name}, {index.state} </h2>
                            </form>
                        )
                    }) : ''}                   
                </div>
        </section>
    );
}

I'm not sure about the cityInfo.map, because I only want to fetch the id from the clicked city, not all of them. Could someone help me?

CodePudding user response:

You can access the id of an item in a list, from the map() function like this:

const [cityId, setCityId] = useState<any>(3477)

const handleClick: FormEventHandler<HTMLFormElement> = (id: number): void => { // set up param
  setCityId(id)
  console.log(id)
}

cityInfo.map((element: any, index: string) => { // <- keep to the naming convention
  return (
    <form key={element.id} onClick={() => handleClick(element.id)}> <!-- directly pass in the id -->
      <h2> {element.name}, {element.state} </h2>
    </form>
  )
}

The first parameter of map() function's callback is the individual element/item, the second is the index. And cityInfo.map((index: any, key: string) => {}) is somewhat misleading. So keeping to the naming convention is a good idea. You can refer to Array.prototype.map() MDN docs.

Please also note that, using index as key is discouraged, you can pass in element.id as key as well.

  • Related