Laravel: Passing data through a controller results in MethodNotAllowedHttpException - php

I have seen this post, however I don't believe it is relevant to my issue because I believe I am correctly passing post data through a post route.
Here is the relevant route code:
Route::get('/pass', 'PageController#pass');
Route::post('/pass/{request}',['uses' => 'PageController#passController']);
I would like to have one controller method for the 'pass' page, but to isolate the issue I have separated them.
Here are the relevant methods in PageController.php:
public function pass(){
return view('pass')->with(array(
'title'=>'Create A Pass'
));
}
public function passRequest($request){
$data['request'] = $request;
$validator = Validator::make($request->all(), [
'studentID' => 'required|max:255',
'teacherID' => 'required|max:255',
'destination' => 'required|max:255',
]);
if ($validator->fails()) {
return redirect('/')
->withInput()
->withErrors($validator);
}
$pass = new Pass;
$pass->student = DB::table('users')->where('studentID', $request->studentID)->first()->id;
$pass->teacher = DB::table('users')->where('teacherID', $request->teacherID)->first()->id;
$pass->destination = $request->destination;
$pass->save();
return view('home')->with(array(
'title'=>'Home',
'success'=>'null'
));
}
I used the method stated here in order to pass data to the controller. If this is bad practice/obsolete I'm open to any suggestions.
This is the form in the 'pass' page responsible for sending the post data
<form action="{{ url('pass') }}" method="POST" class="form-horizontal">
{!! csrf_field() !!}
<fieldset>
<!-- Text input-->
<div class="container">
<div class="form-group">
<label class="col-md-4 control-label" for="studentID">Student ID</label>
<div class="col-md-3">
<input id="studentID" name="studentID" type="text" class="form-control input-md">
</div>
</div>
</div>
<!-- Text input-->
<div class="container">
<div class="form-group">
<label class="col-md-4 control-label" for="teacherID">Teacher ID</label>
<div class="col-md-3">
<input id="teacherID" name="teacherID" type="text" class="form-control input-md">
</div>
</div>
</div>
<!-- Text input-->
<div class="container">
<div class="form-group">
<label class="col-md-4 control-label" for="destination">Destination</label>
<div class="col-md-3">
<input id="destination" name="destination" type="text" class="form-control input-md">
</div>
</div>
</div>
<div class="container">
<div class="form-group">
<div class="col-sm-offset-4 col-sm-6">
<button type="submit" class="btn btn-default">
<i class="fa fa-check"></i> Create Pass
</button>
</div>
</div>
</div>
</fieldset>
</form>
On submission of this form I get the MethodNotAllowedHttpException Exception.
If a stack trace of the error would be helpful, please let me know. If there are any suggestions on style, I'm open to that as well.

This form tag will generate a POST request to the URL /pass:
<form action="{{ url('pass') }}" method="POST" class="form-horizontal">
Your routes file does not allow that. It only allows GET requests to that url, but POST requests to /pass/{request}.
Not sure if its just a copy/paste mistake, but your POST route is set up to call PageController#passController method, but the method you shared from your controller is named passRequest. Those will need to match also.

In addition to what Jeff Lambert pointed out, you should not put the {request} variable in the route.
You should remove that and have laravel inject the Request object for you.
Import the Request class if you haven't already at the top of the class.
use Illuminate\Http\Request;
And your function should look like the following...
public function passRequest(Request $request)
{
...
}
If you have additional parameters to pass through the URL, then you may add them to the route, and add the arguments to the method after Request $request. Laravel will figure out what to do with it.

try this one...
Route::post('/pass/post','PageController#passController')->name('post_insert');
in your html form change to ...
<form action="{{ route('post_insert') }}" method="POST" class="form-horizontal">
change it also ...
public function passRequest(Illuminate\Http\Request $request){
....

Related

Why is my data not being submitted into the database

I tried to create adding/creating a new menu and saved it in the database. However, when I clicked the button, my system didn't show any error but the data is not saved in the database.
adminAddMenu.blade.php
<form>
#csrf
<div class="form-group row">
<label for="categorycode" class="col-sm-3 col-form-label">Category Code</label>
<div class="col-md-4">
<input name="category_code" value="{{old('category_code')}}" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="menutitle" class="col-sm-3 col-form-label">Menu Title</label>
<div class="col-md-4">
<input name="menu_title" value="{{old('menu_title')}}" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="menuprice" class="col-sm-3 col-form-label">Menu Price</label>
<div class="col-md-4">
<textarea name = "menu_price" value="{{old('menu_price')}}" class="form-control"></textarea>
</div>
</div>
<div class="form-group row">
<div class="offset-sm-3 col-sm-9">
<button type="submit" class="btn btn-primary" href="">Submit</button>
</div>
</div>
</div>
</form>
AdminMenuController.php
public function store(Request $request)
{
$menu = new \App\Menu;
$menu->category_code = $request->category_code;
$menu->menu_title = $request->menu_title;
$menu->menu_price = $request->menu_price;
$menu->save();
Session::flash('flash_message', 'Menu is successful! added');
return redirect()->back();
}
web.php
Route::resource('/menus', 'AdminMenuController');
You don't give the form action method where your data will submit. Like you want to send your form data to store method in your controller. So you have to write follow:
<form method="POST" action="{{ route('your route name') }}">
I think you miss the action attribute of your form. Please add action to your form
<form action="{{ YOUR_ROUTER }}">
...
Please add action on form tag.
Like as-
<form action={{ route("your route write here") }} method="post">
I think now it's work's.

Laravel 5 Build url with Laravel Form Get method

I'm trying to create a form that passes data via get to the controller but the URL looks allways like this:
http://example.com/test?_token=VinwWFxKIhKvMqrrEBN5xwXhrmYQjLnOWV8s7dht&param1=horse&param2=cat&param3=dog
But I want something like this:
http://example.com/test/param1=horse/param2=cat/param3=dog
or
http://example.com/test/horse/cat/dog
Route:
Route::get('test/{param1}/{param2}/{param3}', ['as' => 'test', 'uses' => 'MainController#test']);
HTML:
<form action="{{ route('test') }}" method="get">
{{ csrf_field() }}
<div class="col-md-3">
<div class="form-group">
<label for="animal1">animal1</label>
<br>
<input type="text" name="animal1" class="form-control">
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="animal2">animal2</label>
<input type="text" name="animal2" class="form-control">
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="animal3>animal3</label>
<input type="text" name="animal3" class="form-control">
</div>
</div>
<div class="col-md-12">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</form>
The problem is that the test route is reloaded every 10 seconds. Therefore, the form values must be in the URL so that I can process them correctly in the controller.
I've found this question here but that wasn't so helpful
How To Pass GET Parameters To Laravel From With GET Method ?
Thanks for your help!
To do this, you'll need to switch off CSRF token check, which is a bad idea. Or you could use JS to build the query which is not a good idea too.
The best way to handle this is to use POST instead of GET:
<form action="{{ route('test') }}" method="post">
And then change the route to:
Route::post('test', ['as' => 'test', 'uses' => 'MainController#test']);
You can do this via javascript.
You don't need to use form like this.you can just get input values by id(getElementById) and on a button click, format them as you expect (test/{param1}/{param2}/{param3}) and redirect page to that.

Laravel create custom method to get form data

How do I make custom method to get form data? I want this method same with Laravel update method with parameters request and id. I try this but get error.
In controller
public function updatePassword(Request $request, int $id) {
dd($request->all());
}
In route
Route::post('staffs/{id}/upassword', 'Admin\StaffController#updatePassword')->name('admin.staffs.upassword');
In blade file
<form method="post" accept-charset="utf-8" action="{{ action('Admin\StaffController#updatePassword', ['id' => $staff_id]) }}">
<div class="row">
<div class="col-md-3">
<div class="form-group">
<label class="control-label" for="password">New Password</label>
<input class="form-control" name="password" type="password">
</div>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="form-group">
<label class="control-label" for="password_confirmation">Confirm New Password</label>
<input class="form-control" name="password_confirmation" type="password">
</div>
</div>
</div>
<input class="btn btn-primary" type="submit">
</form>
I am using Laravel 5.4.
here are some stuff to fix:
First in the tag you can set the action to :
action="route('admin.staffs.upassword', $staff_id)" since it's
easier to write and since you already gave the route a name, so why
not using it ;)
Second add {{csrf_field() }} right before your form closing tag
</form>
what error are you getting? the error is probably because you are not using {{csrf_field()}} after the form declaration, it is needed so that laravel can validate the request. if you want to get the data from the form you can use:
$request->get('inputname');

Creating New Forms in Laravel 5 and Submitting Them

I wish to clarify the steps to get a new form properly submitted to my database using Laravel 5.2 and Bootstrap 3.
I have the login/register pages set up properly using Laravel's defaults, and they work fine. I now want to create a user profile page accessible to authenticated users. I am using one row in the database for all of their user info. Some fields were filled in during registration, and now I want them to have access to additional fields (while restricting access to certain registration fields like user name).
In the example code below, there are fields to upload a personal photo, enter a first name, and enter a last name. (None of these were done during registration.)
What I have already done (all code is below):
Create the view profile.blade.php
Create a controller profileController.php
Update routes.php in the controller directory.
A note:
When I try to submit the form as it appears below, I get, Type error: Argument 1 passed to App\Http\Controllers\ProfileController::update() must be of the type array, none given.
What are the next steps required to get this page working properly?
profile.blade.php:
#extends('layouts.app')
#section('content')
<div class="container" style="padding-top: 30px;">
<h1 class="page-header">User Profile</h1>
<div class="row">
<!-- left column -->
<div class="col-md-4 col-sm-6 col-xs-12">
<div class="text-center">
<i class="fa fa-user fa-5x"></i>
<h6>Please upload a photo...</h6>
<input type="file" class="text-center center-block well well-sm">
</div>
</div>
<!-- edit form column -->
<div class="col-md-8 col-sm-6 col-xs-12 personal-info">
<form class="form-horizontal" role="form" method="POST" action="{{ url('/profile') }}">
{!! csrf_field() !!}
<div class="form-group">
<label class="col-lg-3 control-label">First name:</label>
<div class="col-lg-8">
<input class="form-control" value="<?php echo Auth::user()->firstname; ?>" id="firstname" name="firstname" placeholder="First..." type="text">
</div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Last name:</label>
<div class="col-lg-8">
<input class="form-control" value="<?php echo Auth::user()->lastname; ?>" id="lastname" name="lastname" placeholder="Last..." type="text">
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label"></label>
<div class="col-md-8">
<button type="submit" class="btn btn-primary">
<i class="fa fa-btn fa-user"></i>Submit
</button>
<span></span>
<input class="btn btn-default" value="Cancel" type="reset">
</div>
</div>
</form>
</div>
</div>
</div>
#endsection
profileController.php:
<?php
namespace App\Http\Controllers;
use App\Http\Requests;
use Illuminate\Http\Request;
class ProfileController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return view('profile');
}
protected function update(array $data)
{
return User::update([
'firstname' => $data['firstname'],
'lastname' => $data['lastname'],
]);
}
}
And I added the following in the routes middleware:
Route::get('/profile', 'ProfileController#index');
Route::post('/profile', 'ProfileController#update');
It's a protocol mismatch, since you're POSTing your form. You need to change your route to
route::post('/profile', 'ProfileController#index');
Using a validator is a great idea, since it will make sure that your input is exactly what you need it to be, and all required fields are filled out.
Your update function should look something like this:
public function update(Request $request)
{
$first_name = $request->input('firstname');
$last_name = $request->input('lastname');
$id = Auth::user()->id;
$user = \App\User::find($id);
$user->firstname = $first_name;
$user->lastname = $last_name;
$user->save();
return view('profile');
// Sanitize, validate, before you do ANYTHING with update
// Instead of returning the update result, you can instead show another view or forward them to another page.
}

Laravel 4 throwing MethodNotAllowedHttpException

I am making a simple registration form that then submits data to my database. However, the problem that I am running into is that the code that should submit the info to the database is not working.
Here's the form that I made using Twitter Bootstrap
<!DOCTYPE html>
<html>
<body>
<div class="modal-body">
<div class="well">
<div id="myTabContent" class="tab-content">
<div class="tab-pane active in" id="login">
<form method="POST" action='/adding_to_table' class="form-horizontal">
<fieldset>
<div id="legend">
<legend class="">Create Your Account</legend>
</div>
<div class="control-group">
<!-- Username -->
<label class="control-label" for="firstname">First Name</label>
<div class="controls">
<input type="text" id="first_name" name="firstname" placeholder="" class="input-xlarge">
</div>
</div>
<div class="control-group">
<!-- Username -->
<label class="control-label" for="lastname">Last Name</label>
<div class="controls">
<input type="text" id="last_name" name="lastname" placeholder="" class="input-xlarge">
</div>
</div>
<div class="control-group">
<!-- Username -->
<label class="control-label" for="email">E-mail</label>
<div class="controls">
<input type="text" id="e_mail" name="email" placeholder="" class="input-xlarge">
</div>
</div>
<div class="control-group">
<!-- Username -->
<label class="control-label" for="username">Username</label>
<div class="controls">
<input type="text" id="username" name="username" placeholder="" class="input-xlarge">
</div>
</div>
<div class="control-group">
<!-- Password-->
<label class="control-label" for="password">Password</label>
<div class="controls">
<input type="password" id="password" name="password" placeholder="" class="input-xlarge">
</div>
</div>
<div class="control-group">
<!-- Button -->
<div class="controls">
<button class="btn btn-primary">Submit</button>
</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
</div>
<script class="cssdeck" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script class="cssdeck" src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
</body>
<html>
This is the route that I am passing to the action field in my form:
Route::get('/adding_to_table', function()
{
return View::make('create');
});
And this is the create.php file that the route (above) is supposed to load which takes care of
the database submission
DB::table('user_info')->insert(
array("First_name" => Input::post('firstname'),
"Last_name" => Input::post("lastname"),
"E-mail" => Input::post("email"),
"Username" => Input::post("username"),
"Password" => Input::post("password"),
)
);
echo "Successfully entered user information into data table";
However, Laravel doesn't like this and is throwing this error at me:
Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException
Open: /Users/brendanbusey/Desktop/php_site/laravelSite/bootstrap/compiled.php
}))->bind($request);
} else {
$this->methodNotAllowed($others);
}
}
protected function methodNotAllowed(array $others)
{
throw new MethodNotAllowedHttpException($others);
}
protected function check(array $routes, $request, $includingMethod = true)
I have double and triple checked to make sure that I am using the names and not the id's from my html form when I'm sending the data via POST and all my names from the columns in my database match the ones in my code. Any help would be greatly appreciated!
You need to have two routes defined, one for GET and one for POST. If you want to use the same adding_to_table url, it should be something like
Route::get('/adding_to_table', function() {
// code to display your form initially
});
Route::post('/adding_to_table', function() {
// code to process the form submission
});
Maybe I'm not understanding you correctly, but it looks like you are using View::make() to try to run your db insert code. I believe View::make() is just intended to render blade templates, so I don't think this will work. Instead you could put that type of thing into a controller method, or even directly into the post route closure. To access the submitted values, you should use Input::get('firstname') etc. In the laravel docs here it explains that
You do not need to worry about the HTTP verb used for the request, as
input is accessed in the same way for all verbs.
You need to change the form opening line in your HTML to this:
<form method="POST" action='adding_to_table' class="form-horizontal">
In your routes.php file, you need to have this:
Route::get('adding_to_table', function()
{
return View::make('create');
});
Route::post('adding_to_table', function()
{
DB::table('user_info')->insert(
array("First_name" => Input::get('firstname'),
"Last_name" => Input::get("lastname"),
"E-mail" => Input::get("email"),
"Username" => Input::get("username"),
"Password" => Input::get("password"),
)
);
});
Change
Input::post() to Input::get()
to retrieve inputs.
Just add {{ csrf_field() }} below your form, like this:
<form method="POST" action='/adding_to_table' class="form-horizontal">
{{ csrf_field() }}
in Create.blade.php
{!! Form::open(array('route' => 'ControllerName.store','method' => 'POST','files' => true)) !!}
in Controller :-
public function store(Request $request)
{
$this->validate($request, [
'first_name' =>'required',
'last_name' => 'required',
'e_mail' =>'required',
'username' => 'required',
'password' =>'required',
]);
ModelName::create($request->all());
return route->(ControllerName.index);
NOTE : check model with all fields are fillable are not .

Categories