DEV Community

Cover image for A Simple Weather app using React and OpenWeatherMap API 🔥
Mohan Kumar
Mohan Kumar

Posted on

A Simple Weather app using React and OpenWeatherMap API 🔥

Hey fellow developers!
This post is about how to create a simple weather app using React and OpenWeatherMap API.

Alt Text

This is how the app will look like.
So, let's get started 🏃‍♂️

Here's the github link in case you're curious react-weather-app and live demo here

Now let's divide this into a few steps,

  1. Setup a React app using Create-React-App
  2. Get the API Key from OpenWeatherMap API
  3. Code, code, code! 👨‍💻

Step - 1

If you're already familiar with create-react-app skip this step and set-up a project or if you're new follow along.

  • Open up a terminal or command prompt in your preferred folder and enter the following command.
npx create-react-app react-weather-app
Enter fullscreen mode Exit fullscreen mode

Like in the image shown below.

Alt Text

After that, navigate to that folder by entering

cd react-weather-app
Enter fullscreen mode Exit fullscreen mode

And then start the project using the following command

npm start
Enter fullscreen mode Exit fullscreen mode

for more details on create-react-app check here

Let's move to next step 😀

Step - 2

  1. Goto OpenWeatherMap website here
  2. Create a new account
  3. Login to that account
  4. Click on My API Key section

Alt Text

Now you can find the API key, if it is not present. Then generate a new API key.

After that copy the API Key (Don't share your API Key publicly).

Step - 3

First we'll store the generated API key in our project.

Alt Text

Create a file called .env in our project's root folder.
Open that file and create a new variable named REACT_APP_API_KEY

Alt Text

It should look like the image as shown above.
That's it for the API key store.

I have used bootstrap, this is totally optional, you can add via cdn or install as an npm package.

Modifying App.js file

Open your App.js file and enter the code as follows,
Add these variables before your return()

// API KEY AND URL
const apiKey = process.env.REACT_APP_API_KEY;
const apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=${state}&appid=${apiKey}`;
Enter fullscreen mode Exit fullscreen mode

Now let's create some states to store the API data and input.

  1. apiData state is used to store the response
  2. getState is used to store the location name from input field
  3. state is used to store a copy of the getState this will be helpful in updating state on button click. You can ignore this state and directly pass getState on the URL as well.
// State
const [apiData, setApiData] = useState({});
const [getState, setGetState] = useState('tamilnadu');
const [state, setState] = useState('tamilnadu');

// API KEY AND URL
const apiKey = process.env.REACT_APP_API_KEY;
const apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=${state}&appid=${apiKey}`;
Enter fullscreen mode Exit fullscreen mode

Now let's make an api request using fetch and useEffect Hook.

// Side effect
useEffect(() => {
  fetch(apiUrl)
    .then((res) => res.json())
    .then((data) => setApiData(data));
}, [apiUrl]);
Enter fullscreen mode Exit fullscreen mode

The useEffect hook is used to perform side effects on your app, this is an alternative to componentDidMount, unmount, etc.. lifecycle hook from react class components.

What this does is, it fetches the data from the given api url and stores in apiData state. This happens only when apiUrl changes thus it will prevent unwanted re-render. [] this is the dependency array this determines when to re-render a componenet, when it is left empty it'll render only once. When we specify a dependency it will render only when it is updated.

Next we'll write some functions to handle the input.

const inputHandler = (event) => {
  setGetState(event.target.value);
};

const submitHandler = () => {
  setState(getState);
};

const kelvinToFarenheit = (k) => {
  return (k - 273.15).toFixed(2);
};
Enter fullscreen mode Exit fullscreen mode
  1. inputHandler this function is used to handle the input field, to get the data and store in getState.
  2. submitHandler this function is used to copy the state from getState to state.
  3. kelvinToFarenheit this function is used to convert kelvin to farenheit, since we get the data from api as kelvin we're using this function.

Finally write this code in your return statement,

return (
  <div className="App">
    <header className="d-flex justify-content-center align-items-center">
      <h2>React Weather App</h2>
    </header>
    <div className="container">
      <div className="mt-3 d-flex flex-column justify-content-center align-items-center">
        <div class="col-auto">
          <label for="location-name" class="col-form-label">
            Enter Location :
          </label>
        </div>
        <div class="col-auto">
          <input
            type="text"
            id="location-name"
            class="form-control"
            onChange={inputHandler}
            value={getState}
          />
        </div>
        <button className="btn btn-primary mt-2" onClick={submitHandler}>
          Search
        </button>
      </div>

      <div className="card mt-3 mx-auto" style={{ width: '60vw' }}>
        {apiData.main ? (
          <div class="card-body text-center">
            <img
              src={`http://openweathermap.org/img/w/${apiData.weather[0].icon}.png`}
              alt="weather status icon"
              className="weather-icon"
            />

            <p className="h2">
              {kelvinToFarenheit(apiData.main.temp)}&deg; C
            </p>

            <p className="h5">
              <i className="fas fa-map-marker-alt"></i>{' '}
              <strong>{apiData.name}</strong>
            </p>

            <div className="row mt-4">
              <div className="col-md-6">
                <p>
                  <i class="fas fa-temperature-low "></i>{' '}
                  <strong>
                    {kelvinToFarenheit(apiData.main.temp_min)}&deg; C
                  </strong>
                </p>
                <p>
                  <i className="fas fa-temperature-high"></i>{' '}
                  <strong>
                    {kelvinToFarenheit(apiData.main.temp_max)}&deg; C
                  </strong>
                </p>
              </div>
              <div className="col-md-6">
                <p>
                  {' '}
                  <strong>{apiData.weather[0].main}</strong>
                </p>
                <p>
                  <strong>
                    {' '}
                    {countries.getName(apiData.sys.country, 'en', {
                      select: 'official',
                    })}
                  </strong>
                </p>
              </div>
            </div>
          </div>
        ) : (
          <h1>Loading</h1>
        )}
      </div>
    </div>
    <footer className="footer">
      <code>
        Created by{' '}
        <a href="https://github.com/imshines" target="none">
          imshines
        </a>{' '}
        using React
      </code>
    </footer>
  </div>
);
Enter fullscreen mode Exit fullscreen mode

I have used bootstrap for styling it's totally optional, the rest of the code is pretty self explanatory. We're just displaying the data from the apiData state object by accessing it's keys.

Alt text

Completed!

That's pretty much it, we have successfully completed the app, this app will show you weather of the state that you enter in the input field.

This is my first blog post kindly let me know your thoughts on this in the comment section below. I'm not a professional Reactjs developer so, let me know if there's any unwanted code present in it. 😁

Thanks for reading, hope you enjoyed 👍
Will see you again in the next one, bye!👋

Top comments (0)