Missing route parameter error : Illuminate \ Routing \ Exceptions \ UrlGenerationException

66 views Asked by At

Route: menu.application.create, here's the full error message :

Illuminate  \  Routing  \  Exceptions  \  UrlGenerationException PHP 8.2.4 10.32.1 Missing required parameter for [Route: menu.application.create] [URI: restaurantApplications/createMenu/{restaurant_id}] [Missing parameter: restaurant_id].

<div class="text-center mt-3">
   <a href="{{ route('menu.application.create', ['restaurant_id' => $restaurantApplication->restaurant_id]) }}" class="btn btn-success">Next</a>
</div>

I created the page restaurantApplications/create.blade.php so that a user (must be authentificated) can access it to register his restaurant , then when he presses on the next button ( the restaurant infos will be saved to the restaurant_applications table and restaurant_id will be sent to the menu route ) and it also takes the user to the next step of the process which is saving the menu application in the page restaurantApplications/createMenu.blade.php : in this page the user will register a description of menu (which will be saved to the menu_applications table) and then starts to add as many dishes as he wants (which will be saved to the dish_applications table) but I'm getting this route missing parameter error is there anyone who can help ?

app/Http/Controllers/MenuApplicationController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\MenuApplication;
use App\Models\DishApplication;
use App\Models\RestaurantApplication;

class MenuApplicationController extends Controller
{
    public function create(Request $request, $restaurant_id = null)
{
    // If $restaurant_id is not provided in the URL parameters, check if it's in the query parameters
    if (!$restaurant_id && $request->has('restaurant_id')) {
        $restaurant_id = $request->input('restaurant_id');
    }

    // Now you have $restaurant_id, and you can use it as needed

    $restaurantApplication = $restaurant_id ? RestaurantApplication::findOrFail($restaurant_id) : null;

    // Pass $restaurantApplication to the view
    return view('restaurantApplications.createMenu', compact('restaurantApplication'));
}

    



    public function store(Request $request)
    {
        // Validate the incoming request data
        $validatedData = $request->validate([
            'description' => 'required|string|max:255',
            'dish_name.*' => 'required|string|max:255',
            'dish_photo.*' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
            'dish_description.*' => 'required|string',
            'dish_price.*' => 'required|numeric',
            // Add other validation rules for menu and dish fields here
        ]);

        // Retrieve the restaurant_id from the session
        $restaurant_id = session('restaurant_id');

        // Create a new menu application
        $menuApplication = MenuApplication::create([
            'restaurant_id' => $restaurant_id,
            'description' => $validatedData['description'],
        ]);

        // Create dish applications
        foreach ($validatedData['dish_name'] as $index => $dishName) {
            // Handle file upload for the dish photo
            $dishPhotoPath = $request->file("dish_photo.$index")->store('dish_photos', 'public');

            DishApplication::create([
                'menu_id' => $menuApplication->id,
                'name' => $dishName,
                'photo' => $dishPhotoPath,
                'description' => $validatedData['dish_description'][$index],
                'price' => $validatedData['dish_price'][$index],
            ]);
        }

        // Clear the session variable after the restaurant application is submitted
        session()->forget('restaurant_id');

        // Redirect or perform any other actions after successful menu application submission
        return redirect()->route('home')->with('success', 'Menu application submitted successfully!');
    }
}

app/Http/Controllers/RestaurantApplicationController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\RestaurantApplication;

class RestaurantApplicationController extends Controller
{
    public function create()
    {
        // Check if the user is coming from the menu application and if a restaurant_id is provided
        $restaurant_id = session('restaurant_id');

        // If a restaurant_id is provided, load the existing restaurant application
        if ($restaurant_id) {
            $restaurantApplication = RestaurantApplication::findOrFail($restaurant_id);
        } else {
            // If not, create a new restaurant application
            $restaurantApplication = new RestaurantApplication();
        }

        return view('restaurantApplications.create', compact('restaurantApplication'));
    }

    public function store(Request $request)
{
    // Validate the incoming request data
    $validatedData = $request->validate([
        'restaurant_id'=>['required|integer'],
        'restaurant_name' => 'required|string|max:255',
        'description' => 'required|string',
        'logo' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
        'location' => 'required|string',
        // Add other validation rules for restaurant fields here
    ]);

    // Handle file upload for the logo
    $logoPath = $request->file('logo')->store('logos', 'public');

    // Create a new restaurant application
    $restaurantApplication = RestaurantApplication::create([
        'restaurant_id' => $validatedData['restaurant_id'],
        'restaurant_name' => $validatedData['restaurant_name'],
        'description' => $validatedData['description'],
        'logo' => $logoPath,
        'location' => $validatedData['location'],
        'user_id' => auth()->id(),
    ]);

    // Example of setting the session variable
    session(['restaurant_id' => $restaurantApplication->restaurant_id]);


    // Pass the restaurantApplication to the menu creation view
    return view('restaurantApplications.createMenu', compact('restaurantApplication'));
}

}

createMenu.blade.php

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Create Menu Application</title>

    <!-- Add Bootstrap CSS (you can replace this with a CDN link if needed) -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

    <style>
        body {
            background-color: #f8f9fa;
            padding: 20px;
        }

        .container {
            max-width: 800px;
            margin: auto;
            background-color: #fff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            margin-top: 50px;
        }

        h2 {
            text-align: center;
            margin-bottom: 30px;
        }

        .mb-3 {
            margin-bottom: 20px;
        }
    </style>
</head>

<body>

   

    <div class="container">
        <h2>Create Menu Application</h2>

        <form action="{{ route('menu.application.store') }}" method="post" enctype="multipart/form-data">
            @csrf

            <!-- Hidden field for restaurant_id -->
            <input type="hidden" name="restaurant_id" value="{{ $restaurantApplication->id }}">

            <!-- Hidden field for menu_id -->
            <input type="hidden" name="menu_id" value="{{ uniqid() }}">

            <div class="mb-3">
                <label for="description" class="form-label">Description</label>
                <textarea class="form-control" id="description" name="description" rows="4" required></textarea>
            </div>

            <!-- Fields for dishes -->
            <div class="mb-3">
                <label for="dishes" class="form-label">Dishes</label>
                <div id="dishes">
                    <div class="dish">
                        <input type="text" class="form-control mb-2" name="dishes[0][name]" placeholder="Dish Name" required>
                        <input type="file" class="form-control-file mb-2" name="dishes[0][photo]">
                        <textarea class="form-control mb-2" name="dishes[0][description]" placeholder="Dish Description" required></textarea>
                        <input type="number" class="form-control" name="dishes[0][price]" placeholder="Price" required>
                    </div>
                    <!-- Add more fields dynamically using JavaScript -->
                </div>
                <button type="button" class="btn btn-secondary mt-2" id="addDish">Add Dish</button>
            </div>
            
            <!-- Add a link/button to go back to the restaurant application -->
            <div class="text-center mt-3">
                <a href="{{ route('restaurant.application.create') }}" class="btn btn-success">Back</a>
            </div>
            @if(isset($restaurantApplication) && $restaurantApplication->id > 0)
                <button type="submit" class="btn btn-primary">Submit </button>
            @endif

        </form>
    </div>

    <script>
        // JavaScript to add dynamic fields for dishes
        let dishCounter = 1;
        document.getElementById('addDish').addEventListener('click', function () {
            const dishesDiv = document.getElementById('dishes');
            const newDish = document.createElement('div');
            newDish.classList.add('dish');
            newDish.innerHTML = `
                <input type="text" class="form-control mb-2" name="dishes[${dishCounter}][name]" placeholder="Dish Name" required>
                <input type="file" class="form-control-file mb-2" name="dishes[${dishCounter}][photo]">
                <textarea class="form-control mb-2" name="dishes[${dishCounter}][description]" placeholder="Dish Description" required></textarea>
                <input type="number" class="form-control" name="dishes[${dishCounter}][price]" placeholder="Price" required>
            `;
            dishesDiv.appendChild(newDish);
            dishCounter++;
        });
    </script>

</body>

</html>

//create.blade.php

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Create Restaurant Application</title>
    <!-- Leaflet CSS and JS -->
    <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
    <!-- Add your additional stylesheets or CDN links here -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <!-- Add additional styles as needed -->
    <style>
        body {
            background-color: #f8f9fa;
            padding: 20px;
        }

        .container {
            max-width: 600px;
            margin: auto;
            background-color: #fff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            margin-top: 50px;
        }

        h2 {
            text-align: center;
            margin-bottom: 30px;
        }

        .mb-3 {
            margin-bottom: 20px;
        }
    </style>
</head>

<body>
    <div class="container">
        <h2>Create Restaurant Application</h2>

        <form action="{{ route('restaurant.application.store') }}" method="post" enctype="multipart/form-data">
            @csrf

            <!-- Add your form fields here -->
            <div class="mb-3">
                <label for="restaurant_name" class="form-label">Restaurant Id</label>
                <input type="text" class="form-control" id="restaurant_id" name="restaurant_id" required>
            </div>

            <div class="mb-3">
                <label for="restaurant_name" class="form-label">Restaurant Name</label>
                <input type="text" class="form-control" id="restaurant_name" name="restaurant_name" required>
            </div>

            <div class="mb-3">
                <label for="description" class="form-label">Description</label>
                <textarea class="form-control" id="description" name="description" rows="4" required></textarea>
            </div>

            <div class="mb-3">
                <label for="logo" class="form-label">Logo</label>
                <input type="file" class="form-control" id="logo" name="logo" accept="image/*" required>
            </div>

            <!-- Hidden field to capture user_id from the active session -->
            <input type="hidden" name="user_id" value="{{ auth()->user()->id }}">

            <!-- Hidden field to set the status to "pending" by default -->
            <input type="hidden" name="status" value="pending">

            <!-- Location Tapping Field -->
            <div class="mb-3">
                <label for="location" class="form-label">Location</label>
                <div id="map" style="height: 300px;"></div>
                <div class="input-group">
                    <input type="text" class="form-control" id="location" name="location"
                        placeholder="Type location or click on the map" aria-describedby="location-btn">
                    <button class="btn btn-primary" type="button" id="location-btn" onclick="getLocation()">Get My
                        Location</button>
                </div>
            </div>

            <div class="text-center mt-3">
                <a href="{{ route('menu.application.create', ['restaurant_id' => $restaurantApplication->restaurant_id]) }}" class="btn btn-success">Next</a>
            </div>


        </form>
    </div>

    <!-- JavaScript to Get Location -->
    <script>
        var map = L.map('map').setView([0, 0], 2); // Default view at coordinates [0, 0] with zoom level 2
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);

        function getLocation() {
            var locationInput = document.getElementById('location').value;
            if (locationInput) {
                // Try to geocode the location input
                fetch('https://nominatim.openstreetmap.org/search?format=json&q=' + encodeURIComponent(locationInput))
                    .then(response => response.json())
                    .then(data => {
                        if (data && data.length > 0) {
                            var lat = parseFloat(data[0].lat);
                            var lon = parseFloat(data[0].lon);
                            map.setView([lat, lon], 15); // Set the map view to the geocoded location with zoom level 15

                            L.marker([lat, lon]).addTo(map) // Add a marker at the geocoded location
                                .bindPopup("Location: " + locationInput).openPopup();
                        } else {
                            alert("Location not found. Please try again.");
                        }
                    })
                    .catch(error => {
                        console.error('Error fetching geocoding data:', error);
                    });
            } else {
                if (navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition(showPosition);
                } else {
                    alert("Geolocation is not supported by this browser.");
                }
            }
        }

        function showPosition(position) {
            var latitude = position.coords.latitude;
            var longitude = position.coords.longitude;

            map.setView([latitude, longitude], 15); // Set the map view to the user's location with zoom level 15

            L.marker([latitude, longitude]).addTo(map) // Add a marker at the user's location
                .bindPopup("Your Location").openPopup();
        }
    </script>

</body>

</html>

Here's the repository of the project: https://github.com/therightnine/RestorationApp

1

There are 1 answers

0
kevin92dev On

Try to ensure that the restaurant_id you're setting is not empty, it might fail if the restaurant_id is null or empty. Try do something like:

@if($restaurantApplication->restaurant_id)
    <a href="{{ route('menu.application.create', ['restaurant_id' => $restaurantApplication->restaurant_id]) }}" class="btn btn-success">Next</a>
@else
    Error: restaurant_id is missing
@endif