Validation working in web.php but not in my Controller

Published 5 months ago by tareenmj

Hi!

I had a problem with validation. For testing purposes, I had all my validation logic stored inside my routes file (web.php), but I attempted to move it into my controller but for some reason it stops working. My code was working perfectly when it was placed in the routes file.

My code is as follows:

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class TaskController extends Controller {
        public function store(Request $request) {
            $data = $request->except('_token');
            $name = "form1_sections/" . $data['nextTab'] . "_form";
            parse_str($data['inputs'], $output);
            $rules = call_user_func($data['currentTab']);
            $validator = Validator::make($output, $rules);
            if ($validator->passes()) {
                return ["view" => view("$name")->render(), "isValid" => true];
            } else {
                return ["isValid" => false, "msg" => json_encode([
                        'errors' => $validator->errors()->getMessages(),
                        'code' => 422
                        ])
                ];
            }
        }

    public function section1() {
            return [
                    'startDate' => 'required| date',
                    'endDate' => 'required| date|different:startDate',
                    'cv' => 'mimes:pdf,doc,docx'
            ];
        }

    //other section methods
}

I genuinely am unsure why this isn't working. I was accessing this route through ajax, but it was working perfectly.

My routes file: Route::post('/roa', '[email protected]');

Best Answer (As Selected By tareenmj)
Snapey

Basically you need to call the function in this class, which is why you need $this-> on the method call.

But there are lots of other ways you could get the rules;

$rules = [
    'section1' =>[
                    'startDate' => 'required| date',
                    'endDate' => 'required| date|different:startDate',
                    'cv' => 'mimes:pdf,doc,docx'
                ],
    'section2' =>[
                    'more field' => 'required| date',
                    'another' => 'required| date',
                    'doit' => 'required'
                ],
    ];

then;

$validator = Validator::make($output, $rules[$data['currentTab']]);

or with a select...case statement

Snapey
Snapey
5 months ago (707,455 XP)

use three backticks ``` before and after your code blocks

tareenmj

@Snapey yea, apologies. I updated it

Snapey
Snapey
5 months ago (707,455 XP)

"isn't working" isn't helpful !

tareenmj

My ajax request ends up breaking and giving me a message for 'error'. When I put this exact same code into my routes file, it works without any problem.

Snapey
Snapey
5 months ago (707,455 XP)

So is it returning a 500 error?

Have you reviewed the response in your browser network tools, or consulted the Laravel error logs?

tareenmj

An error of: master.js:76 POST 500 (Internal Server Error)

and a warning of: master.js:76 [Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.

Any idea? Thanks for your help!

My ajax code (on line 76) looks like:

$.ajax({
            type: 'POST',
            url: '/roa',
            dataType: 'json',
            async: false,
            data: {inputs: formData, nextTab: relatedTabID, currentTab: tabID},
            success: function (data) {
                isValid = data.isValid;
                if (data.isValid) {
                    $('.errorMessage').html('').removeClass('alert alert-danger');
                    $('#tabShow').html((data.view));
                    checkboxFunction();
                    if (relatedTabID === "section6") {
                        section6();
                    }
                } else {
                    var errMsg = jQuery.parseJSON(data.msg);
                    var errorString = '';
                    $.each(errMsg.errors, function (key, value) {
                        errorString += "<li>" + value + '</li>';
                    });
                    $('.errorMessage').html(errorString).addClass('alert alert-danger');
                }
            },
            error: function () {
                alert('error');
            }
        });
Snapey
Snapey
5 months ago (707,455 XP)

The error in the JS is because you got back a 500 error and was not expecting it.

Have you reviewed the response in your browser network tools, or consulted the Laravel error logs?

tareenmj

@Snapey after doing a bit of research it turns out, I need a use Validator at the top of my controller, if I am using the Validator::make. I seem to be having one other problem however, the section1(), section2(), etc functions (i.e. the functions I am invoking using $rules = call_user_func($data['currentTab'])) need to be placed in the web.php, when I remove them from there it gives me an error. Is there any way I can call those functions, if they are stored only in my controller? Thanks a bunch

Snapey
Snapey
5 months ago (707,455 XP)

try

$rules = call_user_func("$this->" . $data['currentTab']);
tareenmj

no luck, it doesn't work. I'm trying to find a way to do this but even after researching, can't find a lot explaining this.

Snapey
Snapey
5 months ago (707,455 XP)

Basically you need to call the function in this class, which is why you need $this-> on the method call.

But there are lots of other ways you could get the rules;

$rules = [
    'section1' =>[
                    'startDate' => 'required| date',
                    'endDate' => 'required| date|different:startDate',
                    'cv' => 'mimes:pdf,doc,docx'
                ],
    'section2' =>[
                    'more field' => 'required| date',
                    'another' => 'required| date',
                    'doit' => 'required'
                ],
    ];

then;

$validator = Validator::make($output, $rules[$data['currentTab']]);

or with a select...case statement

Please sign in or create an account to participate in this conversation.