32
votes

I have a problem with my edit page. When I submit I get this error:

The POST method is not supported for this route. Supported methods: GET, HEAD.

I have no clue where it comes from as I am pretty new to Laravel.

routes(web.php):

Route::group(['middleware' => 'auth'], function () {
Route::get('/', 'ProjectController@index');

Route::get('/projects/{id}', 'ProjectController@show');
Route::post('/create','ProjectController@store');
Route::get('/create', 'ProjectController@create');
Route::get('/projects/{id}/delete', 'ProjectController@destroy');
Route::put('/edit','ProjectController@update');
Route::get('/projects/{id}/edit', 'ProjectController@edit');

});

Controller:

 public function edit($id)
    {
        return view('project.edit',[

            'project' => Project::find($id)
        ]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request)
    {
        $project = Project::find($request->id);
        $project->project_name = $request->input('project_name');
        $project->client = $request->input('client');
        $project->description = $request->input('description');
        $project->time_span = $request->input('time_span');
        $project->text_report = $request->input('text_report');
        $project->created_by = $request->input('created_by');

        $project->save();

        return  redirect('/')->with('success', 'Project aangepast');
    }

enter image description here

13
You currently have the update controller method being called via a PUT method. Either change the form to use PUT or change the line Route::put('/edit','ProjectController@update'); to Route::post('/edit','ProjectController@update');Petay87
thanks for the comment Petay, but when i replace put with post and get a new error returned :Creating default object from empty valueJohnSmith2521
When you find the Project, you should also check the find() return a valid Project object, not a null.user1334621
Have you considered using a resource route/controller? You could just use Route::resource('projects', 'ProjectController'); to have all necessary routes set up. laravel.com/docs/5.8/controllers#resource-controllersbrombeer

13 Answers

38
votes

There are multiple ways you can handle this:

  1. If you insist on using PUT you can change the form action to POST and add a hidden method_field that has a value PUTand a hidden csrf field (if you are using blade then you just need to add @csrf_field and {{ method_field('PUT') }}). This way the form would accept the request.

  2. You can simply change the route and form method to POST. It will work just fine since you are the one defining the route and not using the resource group.

27
votes

I know this is not the solution to OPs post. However, this post is the first one indexed by Google when I searched for answers to this error. For this reason I feel this will benefit others.

The following error...

The POST method is not supported for this route. Supported methods: GET, HEAD.

was caused by not clearing the routing cache

php artisan route:cache
6
votes

I've seen your code in web.php as follows: Route::post('/edit/{id}','ProjectController@update');

Step 1: remove the {id} random parameter so it would be like this: Route::post('/edit','ProjectController@update');

Step 2: Then remove the @method('PUT') in your form, so let's say we'll just plainly use the POST method

Then how can I pass the ID to my method?

Step 1: make an input field in your form with the hidden attribute for example

<input type="hidden" value="{{$project->id}}" name="id">

Step 2: in your update method in your controller, fetch that ID for example:

$id = $request->input('id');

then you may not use it to find which project to edit

$project = Project::find($id)
//OR
$project = Project::where('id',$id);
6
votes

add @method('PUT') on the form

exp:

<form action="..." method="POST">

@csrf  

@method('PUT')



</form>
4
votes

I just removed the slash at the end of url and it began working... /managers/games/id/push/ to:

$http({
  method: 'POST',
  url: "/managers/games/id/push",

This may have to do with upgrading to laravel 5.8?

3
votes

In my case just run the command and worked like charm.

php artisan route:clear
1
votes

The easy way to fix this is to add this to your form.

{{ csrf_field() }}
<input type="hidden" name="_method" value="PUT">

then the update method will be like this :

public function update(Request $request, $id)
{
    $project = Project::findOrFail($id);
    $project->name = $request->name;
    $project->description = $request->description;

    $post->save();
}
1
votes

If you are using a Route::group, with a vendor plugin like LaravelLocalization (from MCAMARA), you need to put POST routes outside of this group. I've experienced problems with POST routes using this plugin and I did solved right now by putting these routes outside Route::group..

0
votes

Hi you dont have to write all the routes just follow the conventions https://laravel.com/docs/5.8/controllers check : Actions Handled By Resource Controller section

Since HTML forms can't make PUT, PATCH, or DELETE requests, you will need to add a hidden _method. When posting a data from n laravel you have to use,

<form action="/foo/bar" method="POST">
@method('PUT')
</form>
0
votes

mainly this type of error generate, 1.first check a code, in code, we define @csrf

<form method ="post" action={{url('project'')}}
   @csrf
   ...... 

2.when we define a wrong variable name, that time also happened this type of problem.

ex. if your database field name "xyz" and you use a "wxyz"

3.if our method is wrong in form,so plz check our method. ex. <form method="post">

0
votes

I had a similiar problem and the only solution was rebooting vagrant which I use as dev enviroment. Beside that, not a single artisan and composer command didn't help.

0
votes

There is a problem with your routes, use the following code:

In Laravel 8: web.php:

Route::middleware(['auth:sanctum', 'verified'])->group(function () {
    Route::prefix('projects')->group(function () {
        Route::get('', 'Projects\ProjectController@index');
        Route::get('create','Projects\ProjectController@create');
        Route::post('create','Projects\ProjectController@store');
        Route::get('show/{id}', 'Projects\ProjectController@show');
        Route::get('delete/{id}', 'Projects\ProjectController@destroy');
        Route::get('edit/{id}', 'Projects\ProjectController@edit');
        Route::put('edit/{id}','Projects\ProjectController@update');
    });
});

app/Http/controllers:

<?php
namespace App\Http\Controllers\Projects;

use App\Http\Requests\Project\ProjectRequest;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class ProjectController extends Controller {
    //---Constructor Function
    public function __construct() {
        $this->middleware('auth:sanctum');
    }//---End of Function Constructor

    //---List Product
    public function index() {
    }//---End of Function index

    //---Create
    public function Create() {
    }//---End of Function Create

    //---Store
    public function Store(ProjectRequest $request) {
    }//---End of Function Store

    //---Show
    public function Show($project) {
    }//---End of Function Show

    //---Destroy
    public function Destroy($project) {
    }//---End of Function Destroy

    //---Edit
    public function Edit($project) {
    }//---End of Function Edit

    //---Update
    public function Update(ProjectRequest $request, $project) {
    }//---End of Function Update
}
?>
0
votes

Yes my problem was identical. But in another way. Your error is caused by your query. If you want to view the error you need to use GET methods for this route. In your case and mine, we are using POST. That way we can't see the real error message...