Building a Weather WebApp with Laravel 11 and RapidAPI

Reading Time: 7 minutes
249 Views

In the ever-evolving world of web development, creating practical and engaging applications is key to keeping users informed and entertained. One of the most popular types of web applications today is the weather app, which provides real-time weather updates and forecasts.

In this blog post, we’ll explore how to build a weather web app using Laravel, a powerful PHP framework, and RapidAPI, a hub that provides access to thousands of APIs.

We’ll create a user-friendly interface where users can enter their location and receive current weather information. By leveraging RapidAPI, we’ll pull in accurate and up-to-date weather data to display in our application.

Let’s get started.

Generate Weather API Keys

Here are the following steps you need to follow to get your API keys for weather application.

>> Open https://rapidapi.com/ and Sign up here. You can register via gmail, github, facebook, or via form.

>> Login to dashboard and search

>> You can choose any weather data service provider. I will prefer Open Weather. Click on it, it will open a page where you will see the keys and code samples.

Read More: Laravel 11 RESTful APIs with Sanctum Authentication

>> Before using these keys and code. You have to select a plan from their list. Select Basic (Free) and Subscribe it.

Now, you have your keys.

Laravel Installation

Open terminal and run this command to create a laravel project.

composer create-project laravel/laravel myblog

It will create a project folder with name myblog inside your local system.

To start the development server of laravel –

php artisan serve

URL: http://127.0.0.1:8000

Assuming laravel already installed inside your system.

Create Weather Controller

Open project terminal and run this command,

php artisan make:controller WeatherController

It will create a controller class with name WeatherController.php inside app/Http/Controllers folder.

Open controller class and write this complete code into it,

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;

class WeatherController extends Controller
{
    public function index(Request $request){

        $weatherResponse = [];

        if($request->isMethod("post")){

           $cityName = $request->city;

            $curl = curl_init();

            curl_setopt_array($curl, [
                CURLOPT_URL => "https://open-weather13.p.rapidapi.com/city/{$cityName}/EN",
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_ENCODING => "",
                CURLOPT_MAXREDIRS => 10,
                CURLOPT_TIMEOUT => 30,
                CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                CURLOPT_CUSTOMREQUEST => "GET",
                CURLOPT_HTTPHEADER => [
                    "x-rapidapi-host: open-weather13.p.rapidapi.com",
                    "x-rapidapi-key: 1ea347413fmsh03e29ab308d2bbap194100jsna287f1c71c65"
                ],
            ]);

            $response = curl_exec($curl);
            $err = curl_error($curl);

            curl_close($curl);
            $weatherResponse = json_decode($response, true);
        }

        return view("weather", [
            "data" => $weatherResponse
        ]);
    }
}

Blade Template Setup

Create a file weather.blade.php inside resources/views folder. Open and write these codes into it.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Weather Application</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
    body {
        margin-bottom: 60px;
        /* Height of the footer */
    }

    .footer {
        position: fixed;
        bottom: 0;
        width: 100%;
        height: 60px;
        /* Height of the footer */
        background-color: #f5f5f5;
    }

    p.card-text {
        margin-top: -10px;
    }
    </style>
</head>

<body>

    <nav class="navbar navbar-expand-lg navbar-dark bg-dark sticky-top">
        <div class="container">
            <a class="navbar-brand" href="#">Weather App</a>
        </div>
    </nav>

    <div class="container">
        <h1 class="mt-5 mb-4">Weather Application</h1>
        <div class="input-group mb-3">
            <form action="{{ route('weather.form') }}" method="post" class="form-inline">
               @csrf
                <div class="d-flex">
                    <div class="form-group">
                        <select class="form-select" name="city" id="city">
                            <option value="-1">-- Select City --</option>
                            <option value="Port Blair">Port Blair</option>
                            <option value="Chandragiri">Chandragiri</option>
                            <option value="Sivasagar">Sivasagar</option>
                            <option value="Chapra">Chapra</option>
                        </select>
                    </div>
                    <button style="margin-left: 20px;" class="btn btn-primary">Search</button>
                </div>
            </form>

        </div>
        <div class="row row-cols-1 row-cols-md-3 g-4">
            <div class="col">
                <div class="card">
                    <div class="card-body">
                        <h5 class="card-title">Looks Like</h5>
                        <br>
                        @if(isset($data['weather'][0]['main']) && $data['weather'][0]['main'] == "Clear")
                            <img src="./images/clear.png" alt="" style="height: 100px;">
                        @endif
                    </div>
                </div>
            </div>
            <div class="col">
                <div class="card">
                    <div class="card-body">
                        <h5 class="card-title">Location Details</h5>
                        <br>
                        <p class="card-text">Country: 
                            <b> 
                                @if(isset($data["sys"]['country'])) 
                                    {{ $data["sys"]['country'] }} 
                                @else
                                  --    
                                @endif 
                            </b>
                        </p>
                        <p class="card-text">Name: 
                                @if(isset($data["name"])) 
                                    {{ $data["name"] }} 
                                @else
                                  --    
                                @endif
                        </p>
                        <p class="card-text">Latitude: 
                                @if(isset($data["coord"]['lat'])) 
                                    {{ $data["coord"]['lat'] }} 
                                @else
                                  --    
                                @endif
                        </p>
                        <p class="card-text">Longitude: 
                                @if(isset($data["coord"]['lon'])) 
                                    {{ $data["coord"]['lon'] }} 
                                @else
                                  --    
                                @endif
                        </p>
                        <p class="card-text">Sunrise: 
                                @if(isset($data["sys"]['sunrise'])) 
                                    {{ $data["sys"]['sunrise'] }} 
                                @else
                                  --    
                                @endif
                        </p>
                        <p class="card-text">Sunset: 
                                @if(isset($data["sys"]['sunset'])) 
                                    {{ $data["sys"]['sunset'] }} 
                                @else
                                  --    
                                @endif
                        </p>
                    </div>
                </div>
            </div>
            <div class="col">
                <div class="card">
                    <div class="card-body">
                        <h5 class="card-title">Temperature  &deg; F</h5>
                        <br>
                        <p class="card-text">Temp: 
                                @if(isset($data["main"]['temp'])) 
                                    {{ $data["main"]['temp'] }} 
                                @else
                                  --    
                                @endif
                        </p>
                        <p class="card-text">Min Temp: 
                                @if(isset($data["main"]['temp_min'])) 
                                    {{ $data["main"]['temp_min'] }} 
                                @else
                                  --    
                                @endif
                        </p>
                        <p class="card-text">Max Temp: <b>--</b></p>
                        <p class="card-text">Feels Like: <b>--</b></p>
                    </div>
                </div>
            </div>
            <div class="col">
                <div class="card">
                    <div class="card-body">
                        <h5 class="card-title">Precipitation &percnt;</h5>
                        <br>
                        <p class="card-text">Humidity: <b>--</b></p>
                        <p class="card-text">Pressure: <b>--</b></p>
                        <p class="card-text">Sea Level: <b>--</b></p>
                        <p class="card-text">Ground Level: <b>--</b></p>
                        <p class="card-text">Visibility: <b>--</b></p>
                    </div>
                </div>
            </div>

            <div class="col">
                <div class="card">
                    <div class="card-body">
                        <h5 class="card-title">Wind m/h</h5>
                        <br>
                        <p class="card-text">Speed: <b>--</b></p>
                        <p class="card-text">Degree: <b>--</b></p>
                        <p class="card-text">Gust: <b>--</b></p>
                    </div>
                </div>
            </div>

        </div>
    </div>
    <br><br>
    <footer class="footer">
        <div class="container">
            <span class="text-muted">© 2024 Weather App. All rights reserved.</span>
        </div>
    </footer>
</body>

</html>

Add Route

Open routes/web.php and add this route into it,

//...
use App\Http\Controllers\WeatherController;

//...
Route::match(["get", "post"], "weather", [WeatherController::class, "index"])->name("weather.form");

Application Testing

Run this command into project terminal to start development server,

php artisan serve

URL: http://127.0.0.1:8000/weather

That’s it.

We hope this article helped you to learn about Building a Weather WebApp with Laravel 11 and RapidAPI in a very detailed way.

Online Web Tutor invites you to try Skillshike! Learn CakePHP, Laravel, CodeIgniter, Node Js, MySQL, Authentication, RESTful Web Services, etc into a depth level. Master the Coding Skills to Become an Expert in PHP Web Development. So, Search your favourite course and enroll now.

If you liked this article, then please subscribe to our YouTube Channel for PHP & it’s framework, WordPress, Node Js video tutorials. You can also find us on Twitter and Facebook.