laravel / nova-issues

554 stars 34 forks source link

Validation #216

Closed DawiePretorius closed 6 years ago

DawiePretorius commented 6 years ago

I am getting the validation error returned and can see them in the network tab, but they are not being displayed?

smayzes commented 6 years ago

Might be helpful to share how you are doing the validation in your Resource Fields.

DSpeichert commented 6 years ago

I am also not getting any feedback on the form about what went wrong. Using the regular Nova ->rules('max:10') validation. v1.0.6

smayzes commented 6 years ago

@DSpeichert I think it expects an array? I've been doing ->rules(['max:10'])

Now I haven't tried max, yet. Just required

DSpeichert commented 6 years ago

I think it's not even important how the validation is done server-side. The important part is how the errors are returned with the 422 Exception.

What I found out by inspecting Vue client-side code in Nova is that your app\Exceptions\Handler.php must have something like this in the render() function:

/**
 * Render an exception into an HTTP response.
 *
 * @param  \Illuminate\Http\Request $request
 * @param  \Exception               $e
 * @return \Illuminate\Http\Response
 */
public function render($request, Exception $e)
{
    if ($request->wantsJson() || $request->isJson()) {
        if ($e instanceof ValidationException)
           // most important part -> errors returned under "errors" key!
           return response()->json(['message' => $e->getMessage(), 'errors' => $e->validator->getMessageBag()], 422);
        // ... all other cases cut from here
        else
            return response()->json(['message' => $e->getMessage()], 500);
    } elseif ($e instanceof HttpException) {
        // this is example
        if (view()->exists('errors.' . $e->getStatusCode()))
            return response()->view('errors.' . $e->getStatusCode(), ['exception' => $e], $e->getStatusCode());
    }

    return parent::render($request, $e);
}

Basically, the response JSON MUST include: 'errors' => $e->validator->getMessageBag()

davidhemphill commented 6 years ago

We are unable to debug your issue without a reproducible code example.

OwenMelbz commented 5 years ago

@davidhemphill @taylorotwell @themsaid as @DSpeichert said - if you have a custom render method in your app for your frontend, then Nova breaks.

Nova relies on your frontend code having

if ($request->wantsJson() || $request->isJson()) {
        if ($e instanceof ValidationException)
           // most important part -> errors returned under "errors" key!
           return response()->json(['message' => $e->getMessage(), 'errors' => $e->validator->getMessageBag()], 422);
        // ... all other cases cut from here
        else
            return response()->json(['message' => $e->getMessage()], 500);
    } elseif ($e instanceof HttpException) {
        // this is example
        if (view()->exists('errors.' . $e->getStatusCode()))
            return response()->view('errors.' . $e->getStatusCode(), ['exception' => $e], $e->getStatusCode());
    }

    return parent::render($request, $e);

If you have something which doesn't do the

return response()->json(['message' => $e->getMessage(), 'errors' => $e->validator->getMessageBag()], 422);

Then it breaks as the response is

{"data":[{"field":"Illuminate\\Validation\\ValidationException","messages":[["The given data was invalid.","\/Users\/owen\/Sites\/spark\/vendor\/laravel\/framework\/src\/Illuminate\/Validation\/Validator.php",315]]}],"meta":{"success":false,"error_code":422}}

Novas error handling should be separate from the frontend otherwise it defeats the point of "you can just drop it in"