React not consuming API after build

Viewed 58

I created an API that consumes a web service from OpenWeather. It works all fine in localhost. However, when a build it and deploy it with Vercel it renders the site, but it does not load the weather. I believe it is because it's not connecting to the OpenWeather API, since the URL is not in the network tab of the Browser's tool.

I'm using CRA (Create React App).

Dependencies

  • Material Ui/Core: 4.11.0
  • Material Ui/icons: 4.9.1
  • Axio: 0.20.0
  • Locale: 0.1.0
  • Moment: 2.29.1
  • Styled-components: 5.2.1

Directory Structure

weather-api
|-- public
|-- src
|    |-- Assets (Images & Icons)
|    |-- Components
|    |-- Content
|    |    |-- Forecast
|    |        |-- Forecast.jsx
|    |    |-- Weather
|    |        |-- styles.js
|    |        |-- Weather.jsx
|    |-- Controller
|    |-- fonts
|    |-- Service
|    |    |-- api.js
|    |-- Styles
|    |-- App.jsx
|    |-- index.js
|    |-- theme.js
|-- .env
|-- .gitignore
|-- package.json
|-- README.md
|-- yarn.lock

api.js

import axios from 'axios';

const api = axios.create({
    baseURL: 'http://api.openweathermap.org/data/2.5/'
});

export default api;

Forecast.jsx


***

import api from "../../Service/api";

***

const Forecast = (props) => {
  const { city } = props;
  const [location, setLocation] = useState(false);
  const [forecast, setForecast] = useState(false);

***

let getForecast = async (city, lat, long) => {
    if (city) {
      let res = await api.get("forecast", {
        params: {
          q: city,
          appid: process.env.REACT_APP_OPEN_WEATHER_KEY,
          cnt: 7,
          units: "metric",
          lang: "pt",
        },
      });
      setForecast(res.data);
    } else {
      let res = await api.get("forecast", {
        params: {
          lat: lat,
          lon: long,
          appid: process.env.REACT_APP_OPEN_WEATHER_KEY,
          cnt: 7,
          units: "metric",
          lang: "pt",
        },
      });
      setForecast(res.data);
    }
  };

  useEffect(() => {
    navigator.geolocation.getCurrentPosition((position) => {
      getForecast(city, position.coords.latitude, position.coords.longitude);
      setLocation(true);
    });
  }, [city]);

  if (!location) {
    return (
      <Fragment></Fragment>
    );
  } else if (!forecast) {
    return <Fragment></Fragment>;
  } else {
    return (
      <Fragment>
        <Grid container justify="center" spacing={1}>
          <Grid item>
            <WeatherCard
              dayWeek={weekDayCap[0]}
              maxTemp={forecast.list[0].main.temp_max}
              minTemp={forecast.list[0].main.temp_min}
              desc={capitalize(forecast.list[0].weather[0].description)}
              imgUrl={forecast.list[0].weather[0].icon}
            />
***
          </Grid>
        </Grid>
      </Fragment>
    );
  }
};

export default Forecast;

Weather.jsx is basically the same call as Forecast.jsx

This is the result on my localhost

This is what I get on my host site

This is the result on my localhost

This is what I get on my host site

("Carregando o clima..." means "Loading the weather...")

1 Answers

I've managed to find a solution.

First, my const appid which was assigning my ID to the API it wasn't being assigned, even though I've set in Vercel. So I've removed from .env file and just added as a string in the parameters.

The second problem was that Chrome was blocking the API call because it didn't think that it was safe. Probably an SSL certificate would resolve it, but the page was meant only to be for study or portfolio, so... Therefore, to make it work, it is needed to set this specific website to allow unsafe content.

By getting around those problems above, I was able to make it work.

Related