What is the Laravel way to check if the POST Request has a field left empty?
Asked Answered
H

5

8

The requirement was to update user roles. The role can be empty(left blank), one, or more than one as provided in the form field roles[].

Here is the view form:

@foreach ($roles as $role)
  <div class="checkbox">
     <label><input name="roles[]" type="checkbox" value="{{$role->id}}" {{ $user->roles->contains($role->id) ? 'checked' : '' }}>{{$role->name}}</label>
  </div>
@endforeach

The condition inside UserController::update() is:

if ($request->roles) {
    // update user roles
}

Everything works fine except for one case. Sometimes the user has to stay without any role.

if($request->roles), isset($request->roles), and !empty($request->roles) .. are all giving the same old fashioned reply(null, '', true/flase).

Case: when there is one or more role(s) assigned:

  +request: ParameterBag {#41 ▼
    #parameters: array:6 [▼
      "_method" => "PUT"
      "_token" => "a8oIPQFBMbhjanikX8v83qeOcfRE0N4UKTcTQDig"
      "name" => "New User Name"
      "email" => "[email protected]"
      "password" => ""
      "roles" => array:2 [▼
        0 => "2"
        1 => "3"
      ]
    ]
  }

Case: when there no role assigned OR need to remove(detach) the previously assigned role:

  +request: ParameterBag {#41 ▼
    #parameters: array:5 [▼
      "_method" => "PUT"
      "_token" => "a8oIPQFBMbhjanikX8v83qeOcfRE0N4UKTcTQDig"
      "name" => "New User Name"
      "email" => "[email protected]"
      "password" => ""
    ]
  }

So the question (requirement) is:

How to differentiate when the field value of an HTML Post form has been submitted as empty(unchecked here) or if there was no such a field in the view form? Is there an eloquent* way in Laravel to find/list the form fileds from the Request object?

[PS: Trying another hidden field or do some frontend jQuery will not be appreciated]

Hols answered 26/3, 2018 at 7:32 Comment(6)
I think isset($request->roles) works fine to check whether there is any role or not submitted from the formLemniscate
have you try ? $request->has('roles')Albinus
$request->has('roles') is giving the same result!Hols
isset($request->roles) says true or false, how do I know when there was a field but still left empty? @ashokpoudelHols
Please remember to check an answer as correct so the question is closed and other users can identify the answer as a solution to their problem. Thank you.Shankle
None of them from the core functions meet the requirement. Not even the server variable $_POST contains all form fields. There is a chance that:$request->filled('roles') may help for 5.5+ users but not others. Another logic (i.e, by taking the input value as an array) helped to to solve my custom requirement and still the question remains.Hols
K
3

You will need to identify this problem in the design of your application.

How to differentiate when the field value of an HTML Post form has been submitted as empty(unchecked here) or if there was no such a field in the view form? Is there an eloquent* way in Laravel to find/list the form fileds from the Request object?

When does that form should not have a roles[] field? You should have a marker that will tell your application that this form doesn't have a roles[] field.

Something like, when this form is used when an ordinary user is updating his/her profile, he/she will not be able to update his/her roles.

Because your problem is indeed the default behavior of forms, as answered in this question: Submit an HTML form with empty checkboxes

So there will be a different process for forms which DO NOT HAVE have a roles field and different process for forms which DO HAVE a roles field.

To add to your implementation, you can retrieve the roles field like this:

$roles = $request->input('roles', []);

After which you can just use sync to the relationship method of your model.

$user->roles()->sync($roles);
Kellen answered 26/3, 2018 at 8:5 Comment(2)
Yes that helps, $request->input('roles', []) will do it.Hols
There is no such a case that: the form should not have roles[]. I had no other way but to ask such a question.Hols
S
18

You can use the laravel request methods has() or filled(), has checks if the parameter is present and filled checks it's present and filled:

if ($request->has('roles')) {
    //
}

or

if ($request->filled('roles')) {
    //
}

Check Laravel documentation for further details on retrieving input from the request object.

EDIT

Since you are using Laravel 5.2 the following rules apply:

  • The has() method checks the parameter is present and filled.
  • The exists() method checks the parameted is present.

Check the code on the repo for more information.

Shankle answered 26/3, 2018 at 7:37 Comment(2)
filled() is not available for versions below 5.5. I think that is the proper way to do it. Unfortunately I still use Laravel 5.2. $request->has('roles') is the same as isset($request->roles)Hols
@EazySam I've updated the answer adding the 5.2 information :)Shankle
W
3

For this you have validations, seems that you need the roles field to be required and exists(to map to a certain table)

You just need to make the validator via artisan command and inject it in the controller method, check out the docs.

ex: php artisan make:request MyCustomRequest Then you should have a request file under: App\Http\Requests You need to set the validation rules as described above:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class MyCustomRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'rules' =>'required|exists:tour_roles_table,id'
        ];
    }
}

Then you can use inject it in your desired method:

class UserController extends Controller {
[...]
    public function update(MyCustomRequest $req)
    {
     [...]
     //at this point validation was successfull, by default Laravel will redirect back with error messages, which can be customized in your request object
    }
[...]
}
Watermelon answered 26/3, 2018 at 7:39 Comment(9)
This definitely seems like a job for validation.Alpenstock
In this case roles are optional, so require them via validation would not be the best solution.Shankle
@Shankle Tou can set fields to be optional as well if OP wants via the sometimes ruleWatermelon
required and exist both don't help (Hols
Yes of course, but he needs to add logic to the condition so the only way you could do that with validation is checking the errorsBag, which IMO would add unnecessary complexity to a pretty simple problemShankle
Don't help in what way?Watermelon
I think a validation is in order because one can have inconsistent data from the start and would need to validate before persisting the request, this is my opinionWatermelon
@Watermelon Don't help to check a condition that: if the form has a field and that was left empty.Hols
If a user doesn't have any roles you should send an empty roles parameter to be consistentWatermelon
K
3

You will need to identify this problem in the design of your application.

How to differentiate when the field value of an HTML Post form has been submitted as empty(unchecked here) or if there was no such a field in the view form? Is there an eloquent* way in Laravel to find/list the form fileds from the Request object?

When does that form should not have a roles[] field? You should have a marker that will tell your application that this form doesn't have a roles[] field.

Something like, when this form is used when an ordinary user is updating his/her profile, he/she will not be able to update his/her roles.

Because your problem is indeed the default behavior of forms, as answered in this question: Submit an HTML form with empty checkboxes

So there will be a different process for forms which DO NOT HAVE have a roles field and different process for forms which DO HAVE a roles field.

To add to your implementation, you can retrieve the roles field like this:

$roles = $request->input('roles', []);

After which you can just use sync to the relationship method of your model.

$user->roles()->sync($roles);
Kellen answered 26/3, 2018 at 8:5 Comment(2)
Yes that helps, $request->input('roles', []) will do it.Hols
There is no such a case that: the form should not have roles[]. I had no other way but to ask such a question.Hols
B
1

try if(empty())

$check = request::get('roles');

if(empty($checkbox)){
  //if checkbox have a empty value do ...
}else{
  //if checkbox have not empty value do .. 
}

for more information click http://php.net/manual/en/function.empty.php

Blaylock answered 26/3, 2018 at 8:50 Comment(1)
Yes/No-True/False! empty(), isset() are all giving the same result here.Hols
M
-1

We were just having issues checking this. We tried everything in this question and nothing worked, but finally we found a solution:

array_key_exists('notes', $request)

https://www.php.net/manual/en/function.array-key-exists.php

Melanosis answered 29/9, 2022 at 14:23 Comment(2)
You'll get the following error if you use this code: Fatal error: Uncaught ArgumentCountError: array_key_exists() expects exactly 2 arguments, 1 givenFlong
I added a second argument on there. ThanksMelanosis

© 2022 - 2024 — McMap. All rights reserved.