can I use route() to make a DELETE request in laravel - laravel

I'm using laravel and trying to delete something. Is it possible to specify the DELETE method on laravel's route()??
e.g
route('dashboard-delete-user', ['id' => $use->id, 'method'=> 'delete'])
or something like that??
EDIT:
What I meant was could I specify that in a link or a button in my blade template. Similar to this:
href="{{ route('dashboard-delete-user') }}

Yes, you can do this:
Route::delete($uri, $callback);
https://laravel.com/docs/master/routing#basic-routing
Update
If for some reason you want to use route only (without a controller), you can use closure, something like:
Route::get('delete-user/{id}', function ($id) {
App\User::destroy($id);
return 'User '.$id.' deleted';
});

No or at least I haven't figure out how to.
The only way for this to work out of the box would be to build a form to handle it. At the very minimum, you would need...
<form action="{{ route('dashboard-delete-user') }}" method="POST">
{{ method_field('DELETE') }}
{{ csrf_field() }}
<button type="submit" value="submit">Submit</button>
</form>
Or you can just create the get route which you are trying to link to and have it handle the logic. It doesn't need to be a route which only respondes to delete requests to delete a resource.

Yes you can, using a URL helper. https://laravel.com/docs/5.2/helpers#urls
There are several options to choose from.

Related

Laravel - route("resource.destroy") calls "resource.show"

This is the web.php
Route::group(['middleware' => 'auth'],
function () {
Route::get('letters/getRows', 'LetterController#getRows')->name('letters.getRows');
Route::get('letters/{letter}/A4', 'LetterController#A4')->name('letters.A4');
Route::get('letters/{letter}/A5', 'LetterController#A5')->name('letters.A5');
Route::resource('letters', 'LetterController');
}
);
I created a link as follow
"<a class='mx-2 h5' href='".route('letters.destroy', $entity->id)."'><i class='icon-remove-circle'></i></a>".
where the $entity->id is the id of the letter. The problem is, it links to show method not the destroy method. What can I do?
Using a form like this
{{ Form::open(array('route' => array('letters.destroy', $entity->id), 'method' => 'delete')) }}
<button type="submit" >Delete Account</button>
{{ Form::close() }}
may solve the problem but I want to use a tag not a form.
update
In the php artisan route:list, the url of destroy and show are the same
thanks
When you use the Route::resource method it will create, among others, a route to DESTROY a resource like this: /letters/:id/ and another route to EDIT the resource: /letters/:id, and one more to SHOW /letters/:id
They all look the same. However, the difference is in the HTTP method/verb used to reach each route.
If you look to the output if php artisan route:list, you will find the list of HTTP methods used. Something like:
GET|HEAD | letters/{letter} | letters.show
PUT|PATCH | letters/{letter} | letters.update
DELETE | letters/{letter} | letters.destroy
Therefore, to show a letter, you use a GET method, to edit a letter, use PUT method, and to destroy/delete, you use a DELETE method.
When you use an a tag, the browser will use the GET method, thus will reach the letters.show route. Html forms, can use POST or GET. Finally to use the DELETE http method, you need a form with hidden input named _method and the value="delete inside the form. Check the docs for more details.
There is also a note about this in LaravelCollective package documentations
Note: Since HTML forms only support POST and GET, PUT and DELETE methods will be spoofed by automatically adding a _method hidden field to your form.
Finally, if you must use an anchor tag <a>, you could use javascript to listen to the click event and submit a form with DELETE method.
Update to add an example:
You can find an example of using an anchor tag to submit the form, in the default app layout in the framework here
And this is a modified version to submit a delete request:
<a class="dropdown-item" href="#"
onclick="event.preventDefault();
document.getElementById('destroy-form').submit();">
{{ __('DELETE') }}
</a>
<form id="destroy-form" action="{{ route('letters.destroy', $entity) }}" method="POST" style="display: none;">
#method('DELETE')
#csrf
</form>
You cant. If you want to make a DELETE request you need to spoof it via a form (method POST, _method DELETE) or use Javascript.
Hyperlinks will cause new requests which will be GET requests. That is just how the web works.

Laravel named route with {parametr}

Route::match(['patch','put'],'/edit/{id}', 'TestController#update')->name('update');
using route() helper in form action I expected to see
https://example.com/edit/1
And what I get using {{ route('update', $article->id) }} is https://example.com/edit?1
Any ideas how to resolve this?
Try passing the id in as an array:
route('update', ['id' => $article->id])
and make sure the form's method attribute is post as well as setting the correct _method value within the form:
<form action="{{ route('upate', ['id' => $article->id]) }}" method="post">
{{ method_field('patch') }}
</form>
I tried your example and it seems to work as expected. Going by the ? in the URL, my guess would be that it is a GET instead of POST in the form? Could you confirm that?

laravel passing parameters from view to route

Using a view with user input. I then want to pass to a route. This what I found so far:
href="{{URL::to('customers/single'$params')}}"
I want to pass the user input as the above $params to my route. This is sample of my route:
Route::get('customer/{id}', function($id) {
$customer = Customer::find($id);
return View::make('customers/single')
->with('customer', $customer);
As soon as I can pass the parameter I can do what I want with the route, which I know how.
Basically you can pass parameter to routes by doing:
Route::get('user/{name}', function($name)
{
//
})
->where('name', '[A-Za-z]+');
In your anchor tag, instead of doing href={{URL...}}, do something like:
{{ URL::to('user/$param') }}
For more information on routing, visit link
This is what I have and works:
<a <button type="button" class="buttonSmall" id="customerView" href="{{URL::to('customer',array('id'=>'abf'))}}" >View</button></a>
But I need the array value 'abf' to be the value of a textbox.
This worked for me in my view anchor tag
href="{{ URL::to('user/'.$param) }}"
instead of what was specified above
href="{{ URL::to('user/$param') }}"
You can user it in View as I used:
<a class="stocks_list" href="/profile/{{ Auth::user()->username }}">Profile</a>
Hope it helps you.

Laravel: delete photo by photo id

I'm trying to delete a photo by it's id, but the routes do not work and I receive a MethodNotAllowedHttpException. What I do:
First I create a form (in my blade template):
{{ Form::open(array("action" => array("cms/albums/destroyphoto", $photo['id']), "method" => "DELETE")) }}
<button type="submit">Delete</button>
{{ Form::close() }}
Then i create my route:
Route::post('cms/albums/destroyphoto/{id}', 'AlbumsController#destroyphoto');
And create my function in the Albumscontroller:
public function destroyphoto($id)
{
dd('Welcome photo');
}
Any suggestions where the routing goes wrong?
Thanks in advance.
Ps. I did composer dump-autoload
When you open your form using "action" you should pass the controller class and action name. You also don't need to specify the method since you're using Route::post
Like this:
{{ Form::open(array("action" => array("AlbumsController#destroyphoto", $photo['id']))) }}
More information

How does Laravel handle PUT requests from browsers?

I know browsers only support POST and GET requests, and Laravel supports PUT requests using the following code:
<?= Form::open('/path/', 'PUT'); ?>
... form stuff ...
<?= Form::close(); ?>
This produces the following HTML
<form method="POST" action="http://example.com/home/" accept-charset="UTF-8">
<input type="hidden" name="_method" value="PUT" />
... form stuff ...
</form>
How does the framework handle this? Does it capture the POST request before deciding which route to send the request off to? Does it use ajax to send an actual PUT to the framework?
It inserts a hidden field, and that field mentions it is a PUT or DELETE request
See here:
echo Form::open('user/profile', 'PUT');
results in:
<input type="hidden" name="_method" value="PUT">
Then it looks for _method when routing in the request.php core file (look for 'spoofing' in the code) - and if it detects it - will use that value to route to the correct restful controller.
It is still using "POST" to achieve this. There is no ajax used.
Laravel uses the symfony Http Foundation which checks for this _method variable and changes the request to either PUT or DELETE based on its contents. Yes, this happens before routing takes place.
You can also use an array within your form open like so:
{{ Form::open( array('route' => array('equipment.update', $item->id ),
'role' => 'form',
'method' => 'put')) }}
Simply change the method to what you want.
While a late answer, I feel it is important to add this for anyone else who finds this and can't get their API to work.
When using Laravel's resource routes like this:
Route::resource('myRoute','MyController');
It will expect a PUT in order to call the update() method. For this to work normally (outside of a form submission), you need to make sure you pass the ContentType as x-www-form-urlencoded. This is default for forms, but making requests with cURL or using a tool like Postman will not work unless you set this.
PUT usually refers to update request.
When you open a form inside laravel blade template using,
{{ Form::open('/path/', 'PUT') }}
It would create a hidden field inside the form as follows,
<input type="hidden" name="_method" value="PUT" />
In order for you to process the PUT request inside your controller, you would need to create a method with a put prefix,
for example, putMethodName()
so if you specify,
{{ Form::open('controller/methodName/', 'PUT') }}
inside Form:open. Then you would need to create a controller method as follows,
class Controller extends BaseController {
public function putMethodName()
{
// put - usual update code logic goes here
}
}

Resources