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
Try to ensure that the
restaurant_id
you're setting is not empty, it might fail if therestaurant_id
is null or empty. Try do something like: