Laravel 7, Missing required parameters for [Route: /xxxxx] error - php

I am trying to pass a value from a view to a controller and use that value in a query. I am getting Missing parameter error. This is my code.
View:
A
Route:
Route::get('/first_letter/{$f_letter}','PtoductController#first_letter')
->name('first_letter');
Controller:
public function index()
{
$products = DB::table('products')
->join('families', 'products.id_family', '=', 'families.id')
->select('products.name')
->where('products.name', 'like', $f_letter.'%')
->get();
return view('product.index', compact('products'));
}

You have two problems
first, fix your route to be like this
Route::get('/first_letter/{f_letter}','PtoductController#first_letter')
->name('first_letter');
when you pass a wildcard in route it is written like this {f_letter} not {$f_letter}
Second, in your controller you need to pass the wildcard in your method as parameter like this
public function index($f_letter)
{
$products=DB::table('products')
->join('families', 'products.id_family', '=', 'families.id')
->select('products.name')
->where('products.name', 'like', $f_letter.'%')
->get();
return view('product.index', compact('products'));
}
you can read more about routing parameters here
At last you can make your a tag more clear like this
A

First, are you sure the controller name is "PtoductController"? Shouldn't it be called ProductController?
Then, if the controller name is correct, remove "$" from the link you call from the controller.
Route::get('/first_letter/{f_letter}', ['uses' => 'PtoductController#first_letter'])
->name('first_letter');
Last, Put $f_letter as a parameter in the "first_letter" function.
public function index($f_letter)
{
//your code
}

Related

Laravel redirecting to the wrong route

web.php
Route::get('/gigs/{id}', [GigsController::class, 'info'])->name('clientside.gigs_info');
Route::get('/gigs/create', [GigsController::class, 'create'])->name('clientside.gigs.create');
Controller
public function create()
{
$categories = Category::select('id', 'name')->get();
return view('clientview.gigs.create', compact('categories'));
}
public function info($id)
{
$gig = Gigs::join('users', 'users.id', '=', 'gigs.created_by')
->join('categories', 'categories.id', '=', 'gigs.category_id')
->select('gigs.*', 'categories.name as category_name', 'users.name as user_name', 'users.surname')
->where('gigs.id', '=', $id)
->orderBy('name', 'ASC')
->firstOrFail();
return view('clientview.gigs.info', compact('gig'));
}
When I try to click this:
<a class="dropdown-item" href="{{ route('clientside.gigs.create') }}">Create Gigs</a>
When I click this I can observe from DebugBar that it directs to route ('clientside.gigs_info')
I think "/create" thinks it is an /{ID} but however, I direct to a different route
Answer by Michael Mano,
Make sure you write on web.php static routes before dynamic.
Just write create route before info route because it is dynamic route (That accept parameter) so always write dynamic route after the static route.
You actually created a dynamic route gigs/{id} so anything that comes after gigs will be called as a parameter of gigs. So to fix this change the order in your web.php like below. So it will search for static route first and then go for dynamic route.
Route::get('/gigs/create', [GigsController::class, 'create'])->name('clientside.gigs.create');
Route::get('/gigs/{id}', [GigsController::class, 'info'])->name('clientside.gigs_info');

Using Model Relationship in a Single Query

Consider the following:
$posts = $this->model->newQuery()
->whereIn('user_id', $user->following) // specifically this line
->orWhere('user_id', $user->id)
->get();
The problem with the above is that there are two queries:
Get following: $user->following
Get posts: Above
This would be much more efficient with the use of a subquery, however, I cannot actually remember the correct way to do it...
I have tried all of the following:
// This was a long-shot...
...->whereIn('user_id', function ($query) use ($user) {
$query->raw($user->following()->toSql());
});
// This works but pretty sure it can be done better with eloquent...
...->whereIn('user_id', function ($query) use ($user) {
$query->select('follow_id')
->from('user_follows')
->where('user_id', $user->id);
});
Is there a way that this can be achieved by using the previously defined relationship $user->following() instead of manually defining the relationship query like the last example above?
Reference
The following relationship is defined as follows:
/**
* Get the users that the user follows.
*/
public function following()
{
return $this->belongsToMany('SomeApp\User\Models\User', 'user_follows', 'user_id', 'follow_id')
->withTimestamps();
}
Use this:
->whereIn('user_id', $user->following()->getQuery()->select('id'))

Check if record exist in collection Laravel

I have controller
public function users() {
$users = User::all('id');
return view('view', compact('users'))
}
Then in my view, i try to check if $users has id I need
#if (contains($users, Auth::user()->id)
do something
#enif
but nothing happens. How can i check if collection has the id i need?
Try this:
if ($users->contains('id', Auth::user()->id)){}
You need to specify the field where to look as the first parameter.

How to print values passed by get method in next view in laravel?

I have passed parameter for my get route by
Show more
And my route is
Route::get('list/{category}', ['as' => 'tour.featured', 'uses' => 'PublicController#productList']);
I want to display the category name in my product-list.blade.php view
This is what i have tried:
{{$_GET['category']}}
This is giving me error of
Undefined index: category
use {{request()->route('category')}}
Use your same route and make your controller like:
public function yourMethod($category)
{
// other stuff here, will return value for $category
return view('someview', COMPACT('category'));
}
And now you can use $category value into your blade file like:
{{ $category }}
Answer reference: laravel 5.2 How to get route parameter in blade?
You are missing one step:
Route::get('list/{category}', ['as' => 'tour.featured', 'uses' => 'PublicController#productList']);
after that, you have to create the productList method in PublicController like
function PublicController(Request $request)
{
echo $request; // will print the data in $product->category
// Now you can pass this value to your view like:
return view('view_name', array('category', $product->category));
}
and get this on view like:
{{$_GET['category']}}

Route precedence order

I have 2 routes with their methods written in same controller[LinkController]:
Route::get('/{country}/{category}', ['as' => 'tour.list', 'uses' => 'LinkController#tourlist']);
Route::get('/{category}/{slug}',['as' => 'single.tour', 'uses' => 'LinkController#singleTour']);
And my methods are:
public function tourlist($country, $category)
{
$tour = Tour::whereHas('category', function($q) use($category) {
$q->where('name','=', $category);
})
->whereHas('country', function($r) use($country) {
$r->where('name','=', $country);
})
->get();
return view('public.tours.list')->withTours($tour);
}
public function singleTour($slug,$category)
{
$tour = Tour::where('slug','=', $slug)
->whereHas('category', function($r) use($category) {
$r->where('name','=', $category);
})
->first();
return view('public.tours.show')->withTour($tour);
}
My code in view is:
{{$tour->title}}
The trouble i am having is the second route [single.tour] returns the view of the first route [tour.list]. I tried to return other view also in 2nd method but still it returns the view of first method. Does laravel have routing precedence ?
This is happening because, Laravel matches routes from the file, and the route which comes earlier and matches the pattern will execute first, you can use regex pattern technique to avoid this like:
Route::get('user/{name}', function ($name) {
//
})->where('name', '[A-Za-z]+'); // <------ define your regex here to differ the routes
See Laravel Routing Docs
Hope this helps!
Both your routes consist of two parameters in the same place. That means any url that matches route 1 will also match route 2. No matter in what order you put them in your routes definition, all requests will always go to the same route.
To avoid that you can specify restrictions on the parameters using regular expressions. For example, the country parameter may only accept two letter country codes, or the category parameter may have to be a numeric id.
Route::get('/{country}/{category}')
->where('country', '[A-Z]{2}')
->where('category', '[0-9]+');
https://laravel.com/docs/5.3/routing#parameters-regular-expression-constraints

Categories