Laravel give array to route, not all values are required - php

I'm getting this error
Missing required parameters for [Route: payment.checkPayment] [URI: {unique_link}/{paymentrequest}/{info}].
Here I encode the array. Note is optional, is also nullable in database.
$info = json_encode(["name" => $request->name, "note" => $request->note]);
This is where I'm sending it to the route
route('payment.checkPayment', [$uniquelink, $paymentrequest, $info])
Route
Route::get('/{unique_link}/{paymentrequest}/{info}', ['as' => 'payment.checkPayment', 'uses' => 'PaymentController#checkPayment']);
How would I fix this? It seems to me I'm sending all of the parameters.

You need to use key-value arrays instead of array-lists as you do:
use:
route('payment.checkPayment', ['unique_link'=>$uniquelink, 'paymentrequest'=>$paymentrequest, 'info'=>$info]);
Reference Laravel Named routes
NOTE it seems you use json-encoded value for the info field, but NOT SURE if this will generate a valid URI. Better check it.

Related

laravel route variables passing null values give url error

I have a route that has 3 optional variables declared as null in Controller
Route::get('gegonota/{gid?}/{cid?}/{nid?}', [
'uses' => 'GegonosController#index',
'as' => 'gegonota'
]);
and even i change the order of the parameter the problem still exists.
public function index($gid = null, $cid = null, $nid = null)
When values of the variables are null are not showing in the url like
http://localhost:8000/gegonota///1
and gives me route errors like it didnt find the specific url.
I have to check and substitute null to 0 so that has something in the url and give no error.
Which is laravel way to do that avoiding all the trouble.
thanks
You may be interested in using Optional Path Parameter as stated in Laravel doc. This means you'll have:
Route::get('gegonota/{gid}/{cid}/{nid?}', [
'uses' => 'GegonosController#index',
'as' => 'gegonota'
]);
Hope this solves the issue.
Update
Even though I cannot say this is the fix since you said rearranging the variable did not solve the issue. I would rather pass those optional variables as request parameters to make things easy, i.e my url would look like:
http://localhost:8000/gegonota/?gid=&cid=&nid=
Therefore, I can already set the default for each of the expected parameters as null rather than deal with inconsistency that may arise from having this kind of wierd /// in my url:
//In a controller
public funtion index()
{
//put them in an array
$my_variables = request()->only(['gid', 'cid', 'nid']);
//or this way
$gid = request()->get('gid');
$cid = request()->get('cid');
$nid = request()->get('nid');
//they are default to null if not existing or have no value
}
This means your route declaration is simple, i.e:
Route::get('gegonota', [
'uses' => 'GegonosController#index',
'as' => 'gegonota'
])
Unless there is an exceptional need to pass those optional variable to the path, its clearly easier and better to have it as request parameters.
Hope this is better.

laravel router argument behaviour

I notice that when you use URL:::action, and set some arguments, sometimes laravel would cast them as GET requests, sometimes not.
Is there anyone know why and how to controller it?
echo URL::action('Campaign\\CampaignController#getIndex',['para' => 1]),"<br>";
echo URL::action('Campaign\\CampaignController#getOtherAction',['para' => 1]),"<br>";
echo URL::action('Campaign\\CampaignController#getOtherAction2',['para' => 1]),"<br>";
Output:
/campaign?para=1
/campaign/other-action/1
/campaign/other-action2/1
Note the getIndex gets argument as GET (?para=1)
This happens because system cannot differentiate requests to getIndex from others if they pass it as url segment.
Means
/campaign/other-action/1 translates to other-action as a method with 1 as param
By your expectation
/campaign/other-action/1 translates to getIndex as a method with other-action/1 as param
Index methods are not suppose to have URL segments as inputs. If you need url segments as inputs then you will have to pass it as a get parameter and thats what laravel is doing for you.
According to your first route output,
if the url is /campaign/1 which means it will expect a method named get1. Another example: if the url is /campaign/param system would expect a method getParam
NOTE for fellow stackoverflow-ers:Consider asking questions before downvoting
I actually found the reason.
when you are using route::controllers method, laravel would assume you have multiple parameters attached to each action
Route::controllers([
'order' => 'Order\OrderController',
'campaign' => 'Campaign\CampaignController'
]);
For example:
campaign/other-action/{VALUE1?}/{VALUE2?}/{VALUE3?}...
So when you pass ['para' => 1, 'para2' => 'abc'], laravel will try to match parameters to action. in this case: campaign/other-action/1/abc
Avoiding to use Route::controllers, an help you take control on laravel router argument behaviour.
For example, in routes.php:
Route::get('campaign/other-action/{id}','Campaign\CampaignController#getOtherAction2')
when you give
echo URL::action('Campaign\\CampaignController#getOtherAction2',['id'=>366, 'para' => 1, 'para2' => 'abc']);
you will get what you want:
campaign/other-action/366?para=1&para2=abc
I hope it is helpful and I now understand why laravel remove Route::controllers from 5.3 version.

Inconsistent behaviour for action() in Laravel

I do not know how to use this in order to always have GET parameters
Route is setup like
Route::controller('/test', TestController::class);
If I specify the getIndex function, it adds GET parameters
>>> action('TestController#getIndex', ['type' => '123'])
=> "http://localhost/test?type=123"
But if I specify anything but the getIndex function it does not add the parameters as GET variables
>>> action('TestController#getSuccess', ['type' => '123'])
=> "http://localhost/test/success/123"
Take a look at the output of php artisan routes --path=/test
Some of the routes (like the one mapped to getSuccess) have parameters and Laravel attempts to match the given parameter array to the route parameters.
Once all the query parameters are accounted for, any excess elements are converted into a query string and appended to the final URL.

Laravel define a put/patch route as the same route name

In Laravel it's quite handy to quickly generate a load of routes by using a route resource:
Route::resource('things'ThingsController');
This will produce all the necessary RESTful routes for CRUD operations. One of these is the PUT/PATCH route which might be defined as follows:
PUT/PATCH things/{id} ThingsController#update things.update
I've read around that it's better to explicitly define each of your routes rather than use a route resource but how would I define the PUT/PATCH route above. I understand that I can do
Route::put('thing/{id}', ['as' => 'things.update']);
or
Route::patch('thing/{id}', ['as' => 'things.update']);
But the second would overwrite or conflict with the first allowing the things.update route name to only refer to either a PUT or PATCH request. How can I explicitly create the combined PUT/PATCH route as created by the resource route?
After tedious searching, try the following;
Route::match(array('PUT', 'PATCH'), "/things/{id}", array(
'uses' => 'ThingsController#update',
'as' => 'things.update'
));
This allows you to restrict request via an array of Verbs.
Or you can limit the resource as so;
Route::resource('things', 'ThingsController',
array(
'only' => array('update'),
'names' => array('update' => 'things.update')
));
Both should provide the same result, but please note they are not tested.
This work for me
Route::match(['put', 'patch'],'thing/{id}', 'ThingsController#update');

Laravel using named routes

Regarding the use of named routes, these 2 lines allow me to access the same page so which is correct?
// Named route
Route::get('test/apples', array('as'=>'apples', 'uses'=>'TestController#getApples'));
// Much simpler
Route::get('apples', 'TestController#getApples');
Is there any reason I should be using named routes if the latter is shorter and less prone to errors?
Named routes are better, Why ?
It's always better to use a named route because insstsead of using the url you may use the name to refer the route, for example:
return Redirect::to('an/url');
Now above code will work but if you would use this:
return Redirect::route('routename');
Then it'll generate the url on the fly so, if you even change the url your code won't be broken. For example, check your route:
Route::get('apples', 'TestController#getApples');
Route::get('apples', array('as' => 'apples.show', 'uses' => 'TestController#getApples'));
Both routes are same but one without name so to use the route without name you have to depend on the url, for example:
return Redirect::to('apples');
But same thing you may do using the route name if your route contains a name, for example:
return Redirect::route('apples.show');
In this case, you may change the url from apples to somethingelse but still your Redirect will work without changing the code.
The only advantage is it is easier to link to, and you can change the URL without going through and changing all of its references. For example, with named routes you can do stuff like this:
URL::route('apples');
Redirect::route('apples');
Form::open(array('route' => 'apples'));
Then, if you update your route, all of your URLs will be updated:
// from
Route::get('test/apples', array('as'=>'apples', 'uses'=>'TestController#getApples'));
// to
Route::get('new/apples', array('as'=>'apples', 'uses'=>'TestController#getApples'));
Another benefit is logically creating a URL with a lot parameters. This allows you to be a lot more dynamic with your URL generation, so something like:
Route::get('search/{category}/{query}', array(
'as' => 'search',
'uses' => 'SearchController#find',
));
$parameters = array(
'category' => 'articles',
'query' => 'apples',
);
echo URL::route('search', $parameters);
// http://domain.com/search/articles/apples
The only reason to name the route is if you need to reference it later. IE: from your page in a view or something, check whether you are in that route.

Categories