I'm passing two parameters to my ShopController
. one is a lang
parameter that is in a route group as a prefix for all routes and the second one is a slug passed through a link.
Here's my controller:
function show($lang, $slug)
{
$product = Product::where('slug', $slug)->first();
return view('shop_show')->with(['product' => $product]);
}
If I pass only one parameter the function takes it as the prefix of the route group, aka the {lang}
parameter and returns this error:
Attempt to read property "name" on null
. so I have to pass two.
I die and dumped both $lang
and $slug
parameters and they are showing the correct values. $lang
is "en"
and $slug
is "laptop-1"
or any other slug I pass in. however after going through the function, it returns an error:
Missing required parameter for [Route: shopShow] [URI: {lang}/shop/{product}] [Missing parameter: product].
This is the route:
Route::group(['prefix' => '{lang}'], function () {
Route::get('/shop/{product}', [ShopController::class, 'show'])->name('shopShow');
});
this is the URL of the page:
http://127.0.0.1:8000/en/shop/laptop-9
Any ideas?
UPDATE: Here's my shop_show.blade.php
view file:
<x-layout :title="$product->name">
<section class="navbar py-2 border-bottom border-2" style="background-color: #eee; font-weight: 500">
<div class="container w-75">
<ul class="breadcrumb">
<li class="breadcrumb-item">
<a class="text-decoration-none" href="{{ route('landingPage', App::getLocale()) }}">Home</a>
</li>
<li class="breadcrumb-item">
<a class="text-decoration-none" href="{{ route('shopIndex', App::getLocale()) }}">Shop</a>
</li>
<li class="breadcrumb-item">
<a class="text-muted text-decoration-none" href="{{ route('shopShow', ['product' => $product->slug, 'lang' => App::getLocale()]) }}">{{$product->name}}</a>
</li>
</ul>
</div>
</section>
<section class="my-5">
<div class="container w-75 d-flex justify-content-between align-items-start">
<div class="w-50">
<div>
<div>
<img id="currentImage" class="active border border-2 rounded-0 p-5 w-75" src='{{ $product->image && file_exists('storage/' . $product->image) ? asset('storage/' . $product->image) : asset('images/not-found.jpg') }}' alt="">
</div>
<div class="product-images">
<div class="product-thumbnails selected">
<img class="w-75" src='{{ $product->image && file_exists('storage/' . $product->image) ? asset('storage/' . $product->image) : asset('images/not-found.jpg') }}' alt="">
</div>
@if ($product->images)
@foreach (json_decode($product->images, true) as $image)
<div class="d-flex align-items-center product-thumbnails">
<img class="w-75" src="{{ file_exists('storage/' . $image) ? asset('storage/' . $image) : asset('images/not-found.jpg') }}" alt="">
</div>
@endforeach
@endif
</div>
</div>
</div>
<div class="card border-0 w-50">
<div>
<h3 class="mb-5">
{{$product->name}}
</h3>
<span class="text-muted" style="font-weight: 500">
{{ $product->details }}
</span>
<div class="h3" style="font-weight: 700">
${{$product->price / 100}}
</div>
<p class="my-3">
{!! $product->description !!}
</p>
<form action="{{ route('cartStore', App::getLocale()) }}" method="POST">
@csrf
<input type="hidden" name="name" value="{{$product->name}}">
<input type="hidden" name="price" value="{{$product->price}}">
<input type="hidden" name="id" value="{{$product->id}}">
<button class="btn py-2 px-3 border border-2 rounded-0 border-secondary" type="submit">Add to Cart</button>
</form>
</div>
</div>
</div>
</section>
@include('partials/might_also_like')
<script>
const currentImage = document.querySelector('#currentImage');
const images = document.querySelectorAll('.product-thumbnails');
images.forEach((element) => element.addEventListener('click', thumbnailClick));
function thumbnailClick(e) {
currentImage.classList.remove('active');
currentImage.addEventListener('transitionend', () => {
currentImage.src = this.querySelector('img').src;
currentImage.classList.add('active');
})
thumbnails.forEach((element) => element.classList.remove('selected'));
this.classList.add('selected');
}
</script>
SOLVED: There was a link in a component within a component within my layout component (3 times nested) that passed only one param, I fixed it by adding another param. It's always a better idea to do localization before defining your routes so that you notice an error immediately instead of having to spend hours going through all your view files.