I am trying to create an API with Laravel 5.6, however, it seems to me that it's not possible to use optional route parameters before/after the parameter.
I'd like to achieve the following:
Route::get('api/lists/{id?}/items',
[
'as' => 'api/lists/items/get',
'uses' => 'ListsController#getListItems'
]);
With the above scenario, if I'm trying to visit api/lists/1/items it shows the page. On the other hand, if I'm trying to visit api/lists/items it says that the page is not found.
What I basically want is if there's no List ID specified, Laravel should fetch all the List ID's items, otherwise it should only fetch the specific ID's items.
Q: How is it possible to the optional parameter in between the 'route words'? Is it even possible? Or is there an alternative solution to this?
As far as I know, it's not possible to use optional parameters in the middle of your url.
You could try a workaround by allowing 0 for the optional parameter and loading all items in this case, as described here.
However, I'd recommend going with two different routes here to match everything you want:
api/lists/items
api/lists/{id?}/items
You have to give default value for optional parameter in the controller:
Route
Route::get('api/lists/{id?}/items', 'ListsController#getListItems');
ListsController
public function getListItems($id = null) {
---your code----
}
Reference
Related
I have dozens of routes like the following list
Route::group([
'where' => ['aNumber' => '.*'],
], function () {
Route::get('air/{aNumber}/tools', 'AirController#tools');
Route::post('air/{aNumber}/handled', 'AirController#handled');
Route::post('air/{aNumber}/notHandled', 'AirController#notHandled');
Route::get('air/{aNumber}/act', 'AirController#act');
Route::post('air/{aNumber}/sendAct', 'AirController#sendAct');
Route::get('air/{aNumber}', 'AirController#show');
});
the {anumber} parameter could be like these 23-349493/4 While this kind of parameter will produce some conflicts with other routes, So for example if we are going to call air/28-23422/sendAct then instead of calling #sendAct route, it'll call #show.
because laravel thinks that /sendAct is part of the parameter. Well, I can fix this problem by adding more where not(Regex) on each of the routes and define the logic that every route should follow, But do you have a better solution for this problem?
No, you are wrong, Laravel will choose show since air/28-23422/sendAct won't hit sendAct because sendAct has as supposed method POST, and not GET.
Instead of:
Route::post('air/{aNumber}/sendAct', 'AirController#sendAct');
try writing
Route::get('air/{aNumber}/sendAct', 'AirController#sendAct');
// ^^^
Or use ^[^\/]* as where clause of the group for aNumber
I'm trying to generate a url with parameter using laravel route helper,
route('frontend.admin.categories.edit', $catRequest->id)
but this is the generated url
http://localhost:8000/admin/categories/edit?1
I need a URL like this
http://localhost:8000/admin/categories/edit/1
And this is my route
Route::get('admin/categories/edit/{id}', 'CategoryController#edit')
->name('admin.categories.edit');
What is the issue here?
You can specify the parameter(s) you are replacing by passing an associative array instead of a variable.
Change,
route('frontend.admin.categories.edit', $catRequest->id)
To
route('frontend.admin.categories.edit', [
'id' => $catRequest->id
]);
Edit #1
You are calling the wrong route, you named your route as admin.categories.edit in the definition yet you are calling frontend.admin.categories.edit within the helper function which is not the originally defined route. So your code should be:
route('admin.categories.edit', [
'id' => $catRequest->id
]);
Reading Material
Named Routes
You need to use an array for your params :
route('frontend.admin.categories.edit', ['id' => $catRequest->id])
If not, all params will be used as $_GET params.
Try to view your route list using php artisan route:list. If you found your route in list with correct Uri then see that you are not again specify that route with same Uri or same alias name in your route file.
Hope this helps :)
You may have another route with the same name right after this one in the code that may be overwriting the above route params, i had the same problem and in my case this is what was happening, i had two routes definitions using the same name but with different http methods like the example below.
Ex:
Route::get('/route1/{param1}');
Route::post('/route1');
redirect()->route('/route1', ['test']); // output: /route1?test
When i've changed it to:
Route::post('/route1');
Route::get('/route1/{param1}');
redirect()->route('/route1', ['test']); // output: /route1/test
then i got the desired result.
So basically this is what I need. I have a router definition like this.
Route::get('view/{postId}', 'PostController#view');
Above router definition will get triggered if the url we request is www.domain.com/view/4. But what I want is I want to appear this url like www.domain.com/[category-of-post]/[titile-of-post] (Ex : www.domain.com/music/easy-chords-in-guitar).
In PostController, I will get the post using the id passed and thus can generate the url what I need. Here is the problem begins. As you can see, I need to redirect to a dynamic url which will look differently for each post. I want to redirect to this dynamic urls but these urls are not defined inside routes.php.
Is this possible in Laravel ?
In short, what I need is, I want to update Illuminate\Routing\RouteCollection::$route array with my dynamically generated url value with corresponding controller action in run time before I am invoking Redirect::to('someurl')
If you need further clarification, I will do it for sure. Please give me your suggestions.
it is simpler than you are thinking.
Route::get('{category}/{title}',['uses' => 'FooController#bar']);
This should be the last route defined in your route list. Any other route should go upper than this one.
this will match www.domain.com/music/easy-chords-in-guitar
rest routes define as you want.
e.g.
Route::get('/',['uses' => 'FooController#home']);
Route::get('about',['uses' => 'FooController#about']);
Route::get('contact',['uses' => 'FooController#contact']);
Route::get('{category}/{title}',['uses' => 'FooController#bar']);
route :
Route::get('action/{slug}', 'HomeController#actionredeemvoucher')->name('home.actionredeemvoucher');
Function in controller:
public function actionredeemvoucher($slug)
{
print_r($slug);
}
I'm migrating the forum section of my website to Laravel 4. I manage the pagination myself. (Not the Laravel built-in one)
My urls currently use the following format:
example.com/forum
example.com/forum/page-1
I'd like to keep it like that after the migration.
My route looks like that:
Route::get('/forum/page-{page?}',
array('uses' => 'ForumController#showForum', 'as' => 'forum'));
But of course it doesn't work when I request the page without a page number.
I can do it like /forum/{pagetext?}-{page?} but I dont want to have to catch the pagetext parameter in my Controller, and I want to only give the $page parameter when I build urls for the page with URL::route().
I've found many examples on Internet but it was always with multiple parameters, no static optional text.
How can I make this "static" portion optional as well ?
I'm thinking to something like an optional group in a regular expression, like /forum/(page-{page})? but how do I do that in Laravel ?
If you truly need the parameter to be optional, I would make the whole segment of that route a single parameter, and you can use a regular expression to enforce it:
Route::get('/forum/{page?}', function($page = null) {
echo 'On page ' . $page;
})->where('page', 'page-[\d]+');
The drawback here is you'll have to get the numeric page number from within your route.
As #Jarek mentioned in the comments, you can also split this up into two different routes:
Route::get('/forum', function() {
echo 'Forum Index';
});
Route::get('/forum/page-{page}', function($page) {
echo 'On page ' . $page;
})->where('page', '[\d]+');
So i have checked out
PHP - Routing with Parameters in Laravel
and
Laravel 4 mandatory parameters error
However using what is said - I cannot seem to make a simple routing possible unless im not understanding how filter/get/parameters works.
So what I would like to do is have a route a URL of /display/2
where display is an action and the 2 is an id but I would like to restrict it to numbers only.
I thought
Route::get('displayproduct/(:num)','SiteController#display');
Route::get('/', 'SiteController#index');
class SiteController extends BaseController {
public function index()
{
return "i'm with index";
}
public function display($id)
{
return $id;
}
}
The problem is that it throws a 404
if i use
Route::get('displayproduct/{id}','SiteController#display');
it will pass the parameter however the URL can be display/ABC and it will pass the parameter.
I would like to restrict it to numbers only.
I also don't want it to be restful because index I would ideally would like to mix this controller with different actions.
Assuming you're using Laravel 4 you can't use (:num), you need to use a regular expression to filter.
Route::get('displayproduct/{id}','SiteController#display')->where('id', '[0-9]+');
You may also define global route patterns
Route::pattern('id', '\d+');
How/When this is helpful?
Suppose you have multiple Routes that require a parameter (lets say id):
Route::get('displayproduct/{id}','SiteController#display');
Route::get('editproduct/{id}','SiteController#edit');
And you know that in all cases an id has to be a digit(s).
Then simply setting a constrain on ALL id parameter across all routes is possible using Route patterns
Route::pattern('id', '\d+');
Doing the above will make sure that all Routes that accept id as a parameter will apply the constrain that id needs to be a digit(s).