React Tutorial – Creating weather App using Material UI

In this article, we will be building a weather app using react js material UI framework. We will also be using OpenWeatherMap API for fetching the weather data from the site.

The idea is simple we are going to create a Card component that will consist of a TextField where the user can write the name of the city.

After getting the name of the city from the input field we will then fetch this to our OpenWeatherMap API. If everything goes right this API will give a response of weather report in JSON format or else it will give an error.

Then we will only take the values which we will be needing for our App from JSON response. And finally, we are going to display that value.

Now without further due let’s build our App.

Implementation

We will build three components :

  • App.js : This component will take input from the user and pass that value to weatherAPI components as prop.
  • weatherAPI.js : This component will take the value from App.js and fetch it to OpenWeatherMap API. After getting a response the JSON object is passed through our Display components.
  • weatherReportDisplay : This component simply display the weather information.

Now let’s start by writing our first component:

App.js


import React from 'react';
import Grid from '@material-ui/core/Grid';
import Card from '@material-ui/core/Card';
import {makeStyles} from '@material-ui/core/styles';
import CardContent from '@material-ui/core/CardContent';
import TextField from '@material-ui/core/TextField';
import WeatherAPI from './weatherAPI';
import bgImg from './images/bg-img.jpg';


const style = makeStyles( theme => ({
                                root : {
                                    marginTop: 50,
                                    display:'flex',
                                    width : 550,
                                    height: 250,
                                    },
                                cardcss : {
                                    backgroundImage : 'url(' + bgImg + ')',
                                    backgroundPosition : 'center' },
                            })
                        )

function App() {
    const classes = style();
    const [city,setCity] = React.useState(null);

    return (
        <Grid className = {classes.root} alignItems='center' container justify>
            <Card className = {classes.cardcss}>
                <CardContent>
                    <TextField autoFocus label="City Name" 
                        onChange={(e)=> {setCity(e.target.value); }}
                    />
                        <WeatherAPI city={city} />
                </CardContent>
            </Card>
        </Grid>
    )
}

export default App;
    

This stateless is simple. We are creating a state name city using a new feature of react js called react hooks. Whenever the user writes the value in the input field the state of the function gets updated and passed it to weatherAPI component.

 

React Tutorial - Creating weather App using Material UI

weatherAPI.js


import React from 'react';
import LinearProgress from '@material-ui/core/LinearProgress';
import Display from './weatherReportDisplay';

const API_KEY = /* Your API key here */
const UNITS = "Metric"
const LANG = "en"

class WeatherAPI extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            weatherReport : null,
            isLoading : true,
            error : null
        }
    }
    componentDidUpdate() {
    var URL = "http://api.openweathermap.org/data/2.5/weather?q=" + this.props.city
                        + "&lang=" + LANG + "&appid=" + API_KEY + "&units="+ UNITS
    fetch(URL).then(response =>{ 
        if(response.ok) {return response.json() }
        else { throw new Error("SOMETHING WENT WRONG")}})
            .then(data => this.setState(
                { weatherReport : data,
                    isLoading: false }))
            .catch(error => this.setState( {error, isLoading : true }));
    }
    render() {

        if(this.state.isLoading) {
            if(this.props.city != null) {
                return (
                    <div> 
                        <LinearProgress  />
                    </div>
                    )
            }
            else return null;
        }
        else {
            return(
                <Display weatherReport = {this.state.weatherReport}/>
            )
        }
    }
}

export default WeatherAPI;

For simplicity of our app here we have used stateful components. Here we have used componentDidUpdate method which will continuously update the state value of this component whenever input field changes. The state of this component holds 3 value:

  1. weatherReport that will hold our JSON response.
  2. isLoading Used for loading bar.
  3. error If server response with any error.

In componentDidUpdate method we are using javascript promise object. Which will contain some value either solved or unsolved when fetching data from the website. The .json() method of promise object converts it into JSON format.

In the render method we first check whether we have got response or not by checking isLoading state. Which only set to false whenever we get a response from the server.

If everything went fine weatherReport state is passed to Display component.

weatherReportDisplay.js


import React from 'react'
import Typography from '@material-ui/core/Typography';
import CardContent from '@material-ui/core/CardContent';
import Box from '@material-ui/core/Box';


function Display({weatherReport}) {
    var lon                = weatherReport.coord.lon;
    var lat                = weatherReport.coord.lat;
    var weathermain        = weatherReport.weather[0].main;
    var weatherdiscription = weatherReport.weather[0].description;
    var temp               = weatherReport.main.temp;
    var pressure           = weatherReport.main.pressure;
    var humidity           = weatherReport.main.humidity;
    var wind               = weatherReport.wind.speed;
    var country            = weatherReport.sys.country;
    var city               = weatherReport.name
    
    return(
        <div>
            <CardContent>
                <Box display = "flex" flexDirection = 'row'>
                    <Box p={1}>
                        <Typography variant = 'h2' color = 'textPrimary'>
                            {city},{country}
                        </Typography>
                        <Typography variant = 'caption' color = 'textSecondary'>
                            {lon}, {lat}
                        </Typography>
                    </Box>
                </Box>
            </CardContent>
            <CardContent>
                <Box display = "flex" flexDirection = 'row-reverse'>
                    <Box p={0}>
                            <Typography variant = 'h4' color = 'textPrimary'>
                                Temp: {temp}<span>&#176;</span>{"C"}
                            </Typography>
                    </Box>
                </Box>
            </CardContent>
            <CardContent>
                <Box display = "flex" flexDirection = 'row-reverse'>
                    <Box p={0}>
                            <Typography variant = 'h6' color = 'textSecondary'>
                                {weatherdiscription}
                            </Typography>
                    </Box>
                </Box>
            </CardContent>
            <CardContent>
            <Box display = "flex" flexDirection = 'row'>
                    <Box p={1}>
                            <Typography variant = 'h6' color = 'textPrimary'>
                                Humidity: {humidity} %
                            </Typography>
                    </Box>
                    <Box p={1}>
                            <Typography variant = 'h6' color = 'textPrimary'>
                                pressure: {pressure} pa
                            </Typography>
                    </Box>
                    <Box p={1}>
                            <Typography variant = 'h6' color = 'textPrimary'>
                                wind: {wind} km/h
                            </Typography>
                    </Box>
                </Box>
            </CardContent>
        </div>

    )
}

export default Display;

This component displays weather information provided by weatherAPI component. Here from the JSON object we have chosen certain values for displaying such as temperature, humidity, pressure, etc. The Box component provided by material UI is used for managing layout.

That’s it now try to implement the above app yourself. After successful implementation try adding more features such as weather icon or litter bit of animation.

OUTPUT:

 

weatherAPP.
WeatherApp

 

 

GITHUB:

https://github.com/Master52/Reactjs-WeatherApp

Sharing is caring!

Leave a Comment

Your email address will not be published. Required fields are marked *

shares
Scroll to Top