1

I have Laravel app with Vue on front end, and Vue calls update method from controller using PUT request.

Request works, model gets updated, but I have issue with redirecting as it is redirecting also as a PUT instead of simple GET?

public function update(MomentsValidationRequest $request, Project $project, Task $task, Moment $moment)
{
    foreach($request->materials as $material){
        $material_id_array[$material['id']] = ['quantity' => $material['quantity']];
    }

    $moment->update($request->all());

    if(isset($material_id_array))
        $moment->materials()->sync($material_id_array);

    return redirect()->back()->with(['alert-type' => 'success', 'message' => 'Moment updated!']);
}

So naturally, I am getting a method not allowed exception because it is redirecting to a route which is supposed to get a previous view only.

Route itself is fine, request method isn't.

For non-believers :)

enter image description here

Also a route:

enter image description here

Norgul
  • 4,613
  • 13
  • 61
  • 144
  • Have you tried to define the redirect within the 'Routes' instead of within the Controller? – cchoe1 Nov 20 '17 at 19:31
  • What do you mean, using new Laravel's `Route::redirect()`? – Norgul Nov 20 '17 at 19:32
  • You simply want to redirect them back after the controller finishes, correct? You most likely have a Route defined that sends a request to the controller specified here. Instead of defining a redirect within this controller, you can define a `back()` method as a return value for the route itself. Here is an example https://laravel.com/docs/5.5/redirects right under 'Creating Redirects'. – cchoe1 Nov 20 '17 at 19:38
  • I don't feel closures are the way to go here. Also, I need to redirect to `/task/{id}` which is not possible to forward then on redirect route without complicating – Norgul Nov 20 '17 at 19:41

3 Answers3

1

I know this is a bit late. But incase anyone stumbles across this.

You state that you're using Vue in the front end. This would suggest that the put request is being made through an axios call.

I can't see this call, so this is only an assumption. But I believe the solution would be to return a json object instead of a response in the controller, and then redirect trigger a redirect from the Vue component itself.

In the controller:

Session::flash('alert-type', 'success');
Session::flash('message', 'Moment updated!');

return response()->json(true);

In the component:

axios.post('/moments', this.moment).then(() => {
    window.location.replace("moments");
});

I believe this is something to do with how axios handles patch requests, it seems to attempt to handle a redirect response automatically, I could be wrong though, so any reply is welcome to if there's a better explanation.

  • I was facing almost this exact same issue, and this is the solution that worked. I thought I could do a redirect with a route, message, and a 303 status code, but couldn't get it to work. – buckthorn Jan 13 '22 at 00:46
0

You can use:

redirect()->back(303)->with(...)
-2

No, redirection is made always with GET but you don't have such route defined. So you should create GET route that will do something with this.

It's possible only to redirect to GET routes.

Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291
  • Is this true? https://laravel.com/docs/5.5/redirects shows an example of using a redirect with a POST request. Technically not a `redirect()` method but it does the same thing by sending the user back to the previous page. – cchoe1 Nov 20 '17 at 19:32
  • 1
    It's done inside POST request but it's redirected to route that is accessible via GET. Redirects are always made to routes available via GET – Marcin Nabiałek Nov 20 '17 at 19:33
  • @Norgul I see, but the problem might be somewhere inside Vue - you are making `PUT` request somewhere instead of `GET`. In Laravel backend redirection will be made using `GET` – Marcin Nabiałek Nov 20 '17 at 19:36
  • But it is strange because Vue code gets inside the method, I tried dumping `$request->method()` and it shows `PUT`...I don't get how that is possible – Norgul Nov 20 '17 at 19:37
  • Really don't know but it must be somewhere in Vue or other part of system you haven't included in your question – Marcin Nabiałek Nov 20 '17 at 20:03