Laravel: how do I pass a value from a form to a controller?
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Laravel: How to Pass Values from Forms to Your Controller (The Complete Guide)
As developers working with the Laravel ecosystem, handling form submissions is one of the most fundamental tasks. You have data entered by a user on the frontend, and you need a reliable, secure way to transport that data into your backend controller method to perform logic, save to the database, or update resources.
The issue you are encountering—receiving an error like "Missing argument" when trying to access $client->id in your controller—usually stems from a misunderstanding of how Laravel handles incoming HTTP requests versus how methods are defined. The key is understanding the difference between Route Parameters, Request Input, and Model Binding.
Let's break down the correct, idiomatic Laravel way to pass data securely and effectively from a form to your controller.
Understanding the Request Lifecycle
When a user submits an HTML form, that data is sent via an HTTP request (usually POST or GET) to a specific route defined in your application. Laravel intercepts this request and packages all the submitted information into an instance of the Illuminate\Http\Request object. This object is the gateway to all the data you need.
If you are trying to pass an ID that identifies a resource (like $client->id), there are three primary ways to achieve this, depending on where the data originates.
Method 1: Using Route Parameters (The Recommended Way for IDs)
For passing IDs that define which record the user is interacting with (like fetching a specific client), the best practice in Laravel is to embed the ID directly into the URL when defining your route. This makes the dependency explicit and easily manageable.
1. Define the Route:
In your routes/web.php file, you define a route that captures the client ID as a parameter:
// routes/web.php
Route::post('/rates/submit/{client}', [RatesController::class, 'postUserRate'])->name('rates.submit');
2. Update the Controller Method:
Your controller method must then accept that parameter directly as an argument. Laravel handles the mapping automatically based on the route definition.
// app/Http/Controllers/RatesController.php
use App\Models\User;
use Illuminate\Http\Request;
class RatesController extends Controller
{
public function postUserRate($client) // The ID is now passed directly here
{
// $client is automatically populated with the ID from the route
$clientId = $client->id;
$currentUser = User::find(Sentry::getUser()->id);
// Use the received ID for your database query
$userRate = DB::table('users_rates')
->where('user_id', $currentUser->id)
->where('client_id', $clientId) // Using the passed ID
->pluck('rate');
if (is_null($userRate)) {
// Handle case where no rate is found
} else {
// ... proceed with saving/updating logic
}
}
}
Method 2: Receiving Data via the Request Object (For Form Fields)
If you are submitting arbitrary data (like a text field for a new rate), you retrieve it from the $request object inside your controller method. This is crucial for security and validation, as you must always validate user input.
1. The Blade Form (Focusing on Input):
Your form needs to use the POST method and include all necessary fields:
<form method="POST" action="{{ route('rates.submit', ['client' => $client->id]) }}">
@csrf
{{-- Pass the client ID via the route, not directly in the form if possible --}}
<input type="hidden" name="client_id" value="{{ $client->id }}">
<label for="rate">Enter new custom client rate:</label>
<input type="text" name="rate" id="rate" placeholder="Enter new custom client rate...">
<button type="submit">Submit</button>
</form>
2. The Controller Method (Using Request Input):
Now, inside your controller, you access the submitted data using $request->input('field_name').
// app/Http/Controllers/RatesController.php
use Illuminate\Http\Request;
class RatesController extends Controller
{
public function postUserRate(Request $request, $client) // We still use route parameter for the client context
{
// Retrieve data from the request object
$rateValue = $request->input('rate');
$clientIdFromRoute = $client->id;
$currentUser = User::find(Sentry::getUser()->id);
$userRate = DB::table('users_rates')
->where('user_id', $currentUser->id)
->where('client_id', $clientIdFromRoute) // Using the ID passed via route context
->pluck('rate');
// ... rest of your logic
}
}
Conclusion: Keeping It Clean and Secure
The error you saw occurred because you were attempting to pass data that Laravel expected to be sourced from the URL (route parameters) or the Request object, but you weren't structuring the request correctly.
For passing IDs like $client->id, Method 1 (Route Parameters) is the cleanest approach as it keeps your controller method focused and leverages Laravel’s routing capabilities. For passing dynamic form inputs (like rates), Method 2 (Request Object) is mandatory, especially when combined with robust validation to ensure that the data you receive is both present and safe before executing database operations.
Always remember that mastering these request patterns is central to building scalable and maintainable applications on Laravel. As you continue your journey, exploring advanced concepts like Eloquent relationships and API design will only deepen your understanding of how powerful frameworks like Laravel can be.