Laravel 5 : on success Validation Request function - laravel-5

In laravel 5, we can now use the Request classes for input validation like so :
public function store(StoreItemRequest $request)
{
$item = Item::create($request->all());
return 'success';
}
When the validation fails, I can get the errors thanks to the response function in the Request class :
public function response(array $errors) {
return response()->json(['errors' => $errors]);
}
But what if the validation succeeds? Is there a function that would get automatically triggered like so :
public function ????(){
if($request->ajax())
return response()->json(['success' => true]);
}
Note: it is required that the content of the function store does NOT get executed if the request is ajax (just as it would not get executed if the validation fails).

Yeah, I found validate method in ValidateWhenResolvedTrait which you could override in your form request class;
public function validate(){
$instance = $this->getValidatorInstance();
if($this->passesAuthorization()){
$this->failedAuthorization();
}elseif(!$instance->passes()){
$this->failedValidation($instance);
}elseif( $instance->passes()){
if($this->ajax())
throw new HttpResponseException(response()->json(['success' => true]));
}
}

Currently there is no such method. You can do this in your request with some "hacks" (like override validate method) but I do not recommend it.
Idea of Request was to move validation/authorization out of controller. If you move successful response to Request than we have the same situation as before (well, name changed).
I would suggest to let controller handle ajax too:
public function store(StoreItemRequest $request)
{
$item = Item::create($request->all());
if($request->ajax())
return response()->json(['success' => true]);
return 'success';
}
Is there a reason why you are trying to achieve this in a request?

Related

While using request validation class through Laravgel API, Error Call to a member function validated() on null

I am using Laravel Request validation class to validate input through API
Reference
I implemented as it is mentioned in documentation and got the following error:
Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function validated() on null
The only difference I feel that they submit a form from a web and I am making a request from postman.
It's been a couple of hours, no clue yet. any help, please?
use Illuminate\Foundation\Http\FormRequest;
class UserTypeRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'user_type' => 'required',
];
}
}
Calling validation in controller:
$this->user_type_request = new UserTypeRequest();
$this->user_type_request->validated();
It should be validation input filed coming from the api, instead its showing null in lavatorial
Try and pass the form request via Dependancy injection:
public function store(UserTypeRequest $request)
{
$var = $request->validated();
...
}
Creating a new form request probably is not validating the previous request (or getting the validation response from the previous request).
You don't need to call the validate function if you're passing the Form Request class in the controller function, just proceed and your request is automatically validated
public function controllerMethod(\App\Http\Requests\UserTypeRequest $request) // Just pass it here
{
// Data is already checked
$data = $request->validated();
}
Hope this helps

What is the argument to pass to a function that uses custom form request validation as a parameter?

I have a custom validator with a function.
Before the function validates the form info using a custom form request, I have a separate function check a few things.
Below is my code, error is thrown.
Note:
I cannot include the 'stockcancel' code in the 'index' function. They need to run before the validation check, and with form requests, the form request gets run before the actual function code.
Error Message: "Call to a member function call() on null"
public function stockcancel(Request $request, product $product) {
if ($request->input('submit') == 'cancel') {
return redirect('/');
}
$new = new shipping;
$this->index($new, $product);
}
public function index(shipping $request, product $product) {
$validated = $request->validated();
// .......
}

Trouble With Validation Form Laravel with Trait (handler) and Form Request

Good morning, i have a trouble.
Let me detail and i will be grateful with yours
I Have a Controller that store the resources - a trait that catch the http_error_codes (404,500)
The trouble is when i try to save a duplicated register on the database the validator didnt work. I am validating with a Request and i want that if is a Query Exception appear a message saying "This field cant not be duplicated (for example)"
Mi Controller
public function store(StoreCategory $request)
{
$data = request()->all();
$newCategory = Category::create($data);
return $this->respondCreated(new CategoryResource($newCategory));
}
My Trait
public function respondCreated($data)
{
$response = $data->response();
return $this->setStatusCode(IlluminateResponse::HTTP_CREATED)->respond(
$response
);
}
public function respond($data, $headers = [])
{
$response = $data;
return $response->setStatusCode($this->statusCode);
}
On my trait i am validating the Status Codes, but all the duplicated registers on my DB appear like 404 because i can not validate
if ($this->isModelNotFoundException($e)) {
return $this->modelNotFound();
} elseif ($this->isHttpException($e) && $e->getStatusCode() == 404 ){
return $this->modelNotFound();
} elseif ($this->isHttpException($e) && $e->getStatusCode() >= 500){
return $this->internalError();
} else{
return $this->badRequest();
}
My Form Request
public function rules()
{
return [
'name' => 'required|max:50|unique:categories',
'parent_id' => 'required'
];
}
If you can help me with anything, I would be very grateful. Thank you in advance, and excuse my English, it's not very good
The problem is that FormRequest causes ValidationException before your controller method runs. If you wish to customize response, this is possible at app/Exceptions/Handler. Do something like:
public function render($request, Exception $exception)
{
if ($exception instanceof ValidationException) {
$errors = $exception->validator->getMessageBag();
//some handling based on errors
}
}
Another way to solve this issue is define at your FormRequest method failedValidation:
protected function failedValidation(Validator $validator)
{
throw new CustomValidationException($validator, $this->response(
$this->formatErrors($validator)
));
}
Then define your own custom exception class with render method(for Laravel >= 5.5) or catch it with instanceof in render method of exception handler
If you want to solve problem without exceptions, you can move validation to controller and create custom response based on your validation logic

Laravel - return variable from Form Requests to Controller

How can I return a variable from Form Requests (App\Http\Requests) to Controller (App\Http\Controllers)?
I am saving a record on function persist() on Form Requests.
My goal is to pass the generated id so that I can redirect the page on edit mode for the user. For some reason, the Controller cannot receive the id from Form Requests.
App\Http\Requests\MyFormRequests.php:
function persist()
{
$business = Business::create([
'cart_name' => $this['cart_name'],
'product' => $this['product']
]);
return $myid = $business->id;
}
App\Http\Controllers\MyControllers.php:
public function store(MyFormRequests $request)
{
$request->persist();
return redirect()->route('mypage.edit.get', $request->persist()->$myid);
}
Important
I must add that this is not the recommended way. Your FormRequest should only be responsible for validating the request, while your Controller does the storing part. However, this will work:
App\Http\Requests\MyFormRequests.php:
function persist()
{
return Business::create([
'business_name' => $this['business_name'],
'nationality' => $this['nationality']
])->id;
}
App\Http\Controllers\MyControllers.php:
public function store(MyFormRequests $request)
{
$id = $request->persist();
return redirect()->route('register.edit.get', $id);
}
A guy name Snapey helped me:
public function store(MyFormRequests $request)
{
$business = $this->persist($request);
return redirect()->route('register.edit.get', $business->id);
}
private function persist($request)
{
....
return $business;
}
hope this could help someone in the future.

Handling Custom Exceptions from PHPUnit (Laravel 5.2)

I'm currently playing around with Exception Handler, and creating my own custom exceptions.
I've been using PHPUnit to run tests on my Controller Resource, but when I throw my custom exceptions, Laravel thinks it's coming from a regular HTTP request rathen than AJAX.
Exceptions return different response based on wether it's an AJAX request or not, like the following:
<?php namespace Actuame\Exceptions\Castings;
use Illuminate\Http\Request;
use Exception;
use Actuame\Exceptions\ExceptionTrait;
class Already_Applied extends Exception
{
use ExceptionTrait;
var $redirect = '/castings';
var $message = 'castings.errors.already_applied';
}
And the ExceptionTrait goes as follows:
<?php
namespace Actuame\Exceptions;
trait ExceptionTrait
{
public function response(Request $request)
{
$type = $request->ajax() ? 'ajax' : 'redirect';
return $this->$type($request);
}
private function ajax(Request $request)
{
return response()->json(array('message' => $this->message), 404);
}
private function redirect(Request $request)
{
return redirect($this->redirect)->with('error', $this->message);
}
}
Finally, my test goes like this (excerpt of the test that's failing)
public function testApplyToCasting()
{
$faker = Factory::create();
$user = factory(User::class)->create();
$this->be($user);
$casting = factory(Casting::class)->create();
$this->json('post', '/castings/apply/' . $casting->id, array('message' => $faker->text(200)))
->seeJsonStructure(array('message'));
}
My logic is like this although I don't think the error is coming from here
public function apply(Request $request, User $user)
{
if($this->hasApplicant($user))
throw new Already_Applied;
$this->get()->applicants()->attach($user, array('message' => $request->message));
event(new User_Applied_To_Casting($this->get(), $user));
return $this;
}
When running PHPUnit, the error I get returned is
1) CastingsTest::testApplyToCasting PHPUnit_Framework_Exception:
Argument #2 (No Value) of PHPUnit_Framework_Assert:
:assertArrayHasKey() must be a array or ArrayAccess
/home/vagrant/Code/actuame2/vendor/laravel/framework/src/Illuminate/Foundation/T
esting/Concerns/MakesHttpRequests.php:304
/home/vagrant/Code/actuame2/tests/CastingsTest.php:105
And my laravel.log is over here http://pastebin.com/ZuaRaxkL (Too large to paste)
I have actually discovered that PHPUnit is not actually sending an AJAX response, because my ExceptionTrait actually changes the response on this. When running the test it takes the request as a regular POST request, and runs the redirect() response rather than ajax(), hence it's not returning the correspond.
Thanks a bunch!
I have finally found the solution!
As I said, response wasn't the right one as it was trying to redirect rathen than return a valid JSON response.
And after going through the Request code, I found out that I need to use also wantsJson(), as ajax() may not be the case always, so I have modified my trait to this:
<?php
namespace Actuame\Exceptions;
trait ExceptionTrait
{
public function response(Request $request)
{
// Below here, I added $request->wantsJson()
$type = $request->ajax() || $request->wantsJson() ? 'ajax' : 'redirect';
return $this->$type($request);
}
private function ajax(Request $request)
{
return response()->json(array('message' => $this->message), 404);
}
private function redirect(Request $request)
{
return redirect($this->redirect)->with('error', $this->message);
}
}

Resources