Laravel validation couldn't store value after validate and give error 500 - ajax

I have a form that using ajax for update data client. In that form there is an input file. Everything is going fine except for updating the file. File is sent, it changed on storage too, but it gives error on validation and didn't change data on database.
Here is the code on the controller :
public function update(Request $request, Client $client)
{
$validatedData = Validator::make($request->all(), [
'name' => 'required|max:255',
'logo'=> 'image|file|max:100',
'level' => 'required|max:1'
]);
$validatedData['user_id'] = auth()->user()->id;
if ($validatedData->fails()){
return response()->json($validatedData->errors());
} else {
if($request->file('logo')){
if($request->oldLogo){
Storage::delete($request->oldLogo);
}
$validatedData['logo'] = $request->file('logo')->store('logo-clients');
}
$validateFix = $validatedData->validate();
Client::where('id', $client->id)->update($validateFix);
return response()->json([
'success' => 'Success!'
]);
}
}
It gives error on line :
$validatedData['logo'] = $request->file('logo')->store('logo-clients');
With message :
"Cannot use object of type Illuminate\Validation\Validator as array"
I use the same code that works on another case, the difference is the other not using ajax or I didn't use Validator::make on file input. I guess it's just wrong syntax but I don't really know where and what it is.

To retrieve the validated input of a Validator, use the validated() function like so:
$validated = $validator->validated();
Docs:
https://laravel.com/docs/9.x/validation#manually-creating-validators
https://laravel.com/api/9.x/Illuminate/Contracts/Validation/Validator.html

$validatedData is an object of type Illuminate\Validation\Validator.
I would say the error is earlier there as well as this line should give an error also:
$validatedData['user_id'] = auth()->user()->id;
As ericmp said, you first need to retrieve the validateddata to an array and then work with it.

Related

Method Illuminate\Http\Request::first does not exist in laravel 6 error

I am trying to implement multiple column as unique(title,created_by). A user can not create duplicate title.
The validation give me error both in separate request class also.
The validation code is:
$created_by = auth()->user()->id;
$this->validate($request, [
'title' => 'required|max:50|unique:register_types,title,null,id,created_by,'.$created_by
]);
The code give error as "Method Illuminate\Http\Request::first does not exist"
But Validator method works successfully.
The code is:
$validator = \Validator::make($request->all(),[
'title' => 'required|max:50|unique:register_types,title,null,id,created_by,'.$created_by
]);
if ($validator->fails()) {
return $validator->errors();
}
I want to use first clean code pattern. How is it possible ?
I got my problem.
Some days ago, I have added a condition at render method in handler class:
elseif ($exception instanceof ValidationException) {
return $exception->first();
}
Solution:
At this time, just I blocked this condition.
Problem solved.

How can I use Laravel Validation in the API, it's returning my view now?

I have this route in route/api.php:
Route::post('/register', 'LoginController#register');
My LoginController
class LoginController extends Controller {
public function register(Request $request) {
$this->validate($request, // <-- using this will return the view
// from **web.php** instead of the expected json response.
[
'email' => 'required|email',
'firstName' => 'required|alpha_dash',
'lastName' => 'required',
'password' => 'required|confirmed',
]);
$input = $request->all();
//$plain_password = $input['password'];
$input['uuid'] = uuid();
$input['password'] = Hash::make($input['password']);
$user = User::create($input);
dd($errors);
$response['succes'] = true;
$response['user'] = $user;
return response($response);
}
}
Why does adding a validation call change the behaviour to returning my view / the wrong route. I want the api to validate my request too, not just my "frontend".
When you use Laravel's validate method from controller it automatically handles/takes the step if the validation fails. So, depending on the required content type/request type, it determines whether to redirect back or to a given url or sending a json response. Ultimately, something like thos following happens when your validation fails:
protected function buildFailedValidationResponse(Request $request, array $errors)
{
if ($request->expectsJson()) {
return new JsonResponse($errors, 422);
}
return redirect()->to($this->getRedirectUrl())
->withInput($request->input())
->withErrors($errors, $this->errorBag());
}
So, if the first if statement is true then you'll get a json response and it'll be true if you either send an ajax request or if you attach a accept header with your request to accept json response (When requesting from a remote server). So, make sure your request fulfills the requirements.
Alternatively, you can manually validate the request using the Validator component and return a json response explicitly if it fails.

Laravel if one of the fields is not set, laravel throws error

I have very big problem.
When I submit my form with data everything goes well, but when I won't fill one field in my form laravel throw error MethodNotAllowedHttpException in RouteCollection.php line 218
I have validation in my controller but it does not change anything. When the form is empty it throws an error.
Somebody has a solution for this error?
In your route for this form post use veriables as optional. Use ? In your route definition.
/{var?}/{var2?}/......
From laravel docs-
Occasionally you may need to specify a route parameter, but make the presence of that route parameter optional. You may do so by placing a ? mark after the parameter name. Make sure to give the route's corresponding variable a default value:
Route::get('user/{name?}', function ($name = null) {
return $name;
});
Route::get('user/{name?}', function ($name = 'John') {
return $name;
});
or
// validate the info, create rules for the inputs
$rules = array('data_rozpoczecia' => 'required', 'data_zakonczenia' => 'required');
// run the validation rules on the inputs from the form
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) { return redirect()->back(); } else{ //do what you want. }

Image validation not working If using ajaxForm

I tried googling and saw other questions posted at this forum but could not find any solution for my issue. I am using Jquery ajaxForm method to submit form. My form contains one file field too in the form that can be used to upload a picture. I have defined the validation in my model. But the issue is even i am uploading a correct jpg file, still i am getting error message that
Argument 1 passed to Illuminate\\Validation\\Factory::make() must be of the type array, object given.
Javascript Code
$('#create_form').ajaxForm({
dataType:'JSON',
success: function(response){
alert(response);
}
}).submit();
Controllder Code
if ($file = Input::file('picture')) {
$validator = Validator::make($file, User::$file_rules);
if ($validator->fails()) {
$messages = $validator->messages();
foreach ($messages->all(':message') as $message) {
echo $message; exit;
}
return Response::json(array('message'=>$response, 'status'=>'failure'));
} else {
// do rest
}
}
Model Code
public static $file_rules = array(
'picture' => 'required|max:2048|mimes:jpeg,jpg,bmp,png,gif'
);
POST Request
I know that my validation defined in the model expects an array. But by passing $file in the validator, an object is passed. Then i changed the code like:
$validator = Validator::make(array('picture' => $file->getClientOriginalName()), User::$file_rules);
Now i am getting error:
The picture must be a file of type: jpg, JPEG, png,gif.
The problem is you pass file object directly to validate. Validator::make() method takes all four parameters as array. Moreover, you need to pass the whole file object as value so that Validator can validate mime type, size, etc. That's why your code should be like that.
$input = array('picture' => Input::file('picture'));
$validator = Validator::make($input, User::$file_rules);
if ($validator->fails()) {
$messages = $validator->messages();
foreach ($messages->all(':message') as $message) {
echo $message; exit;
}
return Response::json(array('message'=>$response, 'status'=>'failure'));
} else {
// do rest
}
Hope it will be useful for you.
Try rule like this.
$rules = array(
'picture' => 'image|mimes:jpeg,jpg,bmp,png,gif'
);
or try removing 'mimes'

One-shot laravel validator

I have a form where someone searches for something. Based on this form, I validate if the input is correct:
$validator = Validator::make(Input::all() , array(
'address' =>'required',
));
if($validator->fails()) {
return Redirect::to('/')->withErrors($validator);
}
After this, I want to validate something else (that a result object isn't empty), which is completely unrelated to the search. In other words, it's NOT input from a form.
1) Do I create another validator to validate this? Or
2) Is there a better way to simply check this value and spawn an object that can be returned with "withErrors"?
UPDATE
This isn't working for me:
$validator = Validator::make(
array(
'searches' => sizeof($search)
) ,
array(
'searches' => 'required|min:1'
)
);
if($validator->fails()) {
return Redirect::to('/')->withErrors($validator);
}
It's not working because for some reason it's picking up that the "searches" item should only be validated "sometimes"
you have two ways. one is custom validator
or there is a simpler way,
suppose,
private function foo()
{
$data = ''; //retrieved the data error here with whatever call you want to make
return !empty($data) ? true : false;
}
in the controller,
public function bar()
{
if(!$this->foo())
{
$messages = new \Illuminate\Support\MessageBag;
// you should use interface here. i directly made the object call for the sake of simplicity.
$messages->add('custom', 'custom error');
return Redirect::back()->withErrors($messages)->withInput();
}
}
in the view:
#if($errors->has('custom'))
<p>custom error output.</p>
#endif
it is just the outline to give you the idea.

Resources