I am sending json object with sub json object to server.I want to validate sub json object in laravel5.1 form validation method.
My object is,
{
"empType": {
"id": 2,
"title": "Part Time",
"status": 1
},
"salutation": "Mr",
"name": "Shihabuddeen",
"employee_code": "EMP1001"
}
My form validation method is,
public function rules() {
return [
'salutation' => ['required'],
'name' => ['required', 'max:100'],
'employee_code' => ['required', 'max:100'],
"empType.id" => ['required', 'integer'],
];
}
Here all other validations are working fine except "empType.id" => ['required', 'integer'].
Is there any way to do this validation?
Related
I have a Laravel 9 API.
I am posting the following json to an endpoint.
{
"shapes": [
{
"type": "Point",
"coordinates": [1, 2]
},
{
"type": "MultiPolygon",
"coordinates": [
[
[
[1, 2],
[3, 4],
[5, 6],
]
]
]
}
]
}
I have some form validation (in a form request class) that needs to validate the coordinates given differently based on the type.
I.e. Apply the PointCoordinatesValidator rule if the shape's type is Point or apply the MultiPolygonCoordinatesValidator rule if the shape's type is MultiPolygon.
public function rules()
{
return [
'shapes' => 'required|array|min:1',
'shapes.*.type' => [
'required',
'string',
'in:Point,MultiPolygon',
],
'shapes.*.coordinates' => [
'required',
request()->input('shapes.*.type') == 'Point' ?
new PointCoordinatesValidator :
new MultiPolygonCoordinatesValidator,
],
];
}
However, when running this, the custom MultiPolygonCoordinatesValidator rule is being applied to both shapes, not just the shape where it's type == MultiPolygon.
I can see that
request()->input('shapes.*.type') is Point for shapes.0 and MultiPolygon for shapes.1
Am I expecting too much from the validation? Is it possible to validate the different items in the array differently based on a value in that array?
Just pass the array element in and then implement the type check in your rule:
'shapes.*' => [
'required',
new CoordinatesValidator(),
],
Then, in the rule, the $value will contain the type and the coordinates.
It definitely is possible, but not by checking request()->input('shapes.*.type') == 'Point'; that * is a wildcard, and isn't really checked on each iteration.
You can construct the rules from the input, but it's a bit of an anti-pattern, and might have issues if type is null, or similar.
Give this a shot:
public function rules() {
$rules = [
'shapes' => 'required|array|min:1',
'shapes.*.type' => [
'required',
'string',
'in:Point,MultiPolygon',
]
];
foreach(request()->input('shapes', []) as $index => $shape) {
$rules["shapes.{$index}.coordinates"] = [
'required',
$shape['type'] == 'Point' ? new PointCoordinatesValidator() : new MultiPolygonCoordinatesValidator()
];
}
return $rules;
}
Using that, you'll get something like this:
[
'shapes' => 'required|array|min:1',
'shapes.*.type' => [
'required',
'string',
'in:Point,MultiPolygon'
],
'shapes.0.coordinates' => [
'required',
new PointCoordinatesValidator()
],
'shapes.1.coordinates' => [
'required',
new MultiPolygonCoordinatesValidator()
]
// And so on...
]
Your $rules array can get pretty large, depending on the number of shapes being uploaded, but this should allow you to explicitly target certain validation rules for each shape, depending on the type supplied.
If in a form request I have rules
[
'items' => ['required', 'array'],
'items.*' => ['required', 'numeric'],
]
Then error message returns like this:
"items.0" => array:1 [
0 => "The selected items.0 is invalid."
]
Is there any way to have the message look like "The selected items #1 is invalid" or something similar, that is actually human readable?
Please note, I need this for the whole system globally, there's already >500 form request classes, although not that many are using array validation, so changing extended class or adding a trait wouldn't be too horrible
Try This,
[
'items' => ['required', 'array'],
'items.*' => ['required', 'numeric'],
],
[
'items.required' => 'Your Message',
]
If you are using custom Request then You can do like this:
public function rules()
{
$rules = [];
foreach ($this->request->get('items') as $key => $value) {
$rules[$key] = 'required';
}
return $rules;
}
Hope This Help you
I am creating a laravel multiple array of an object API but my controller gives an error
Below is the request
[
{
"ProductTitle": "Clarks Men's Tilden Cap Oxford shoe",
"ProductColor": "Dark tan leather",
"ProductImage": "imageurl"
}
,
{
"ProductTitle": "Clarks Men's Tilden Cap Oxford shoe",
"ProductColor": "Dark tan leather",
"ProductImage": "imageurl"
}
]
My API store controller is as below
public function store(Request $request)
{
$input = $request;
$validator = Validator::make($input, [
'ProductTitle' => 'required',
'ProductColor' => 'required',
'ProductImage' => 'required'
]);
if($validator->fails()){
return $this->sendError('Validation Error.', $validator->errors());
}
$cartdetails=shopCartDetails::create($request->all());
return $this->sendResponse( $cartdetails,'Great success! cart details posted');
}
Am getting error
Argument 1 passed to Illuminate\Validation\Factory::make() must be
of the type array, object given,
the results have now changed to
{
"success": false,
"message": "Validation Error.",
"data": {
"ProductTitle": [
"The product title field is required."
],
"ProductColor": [
"The product color field is required."
],
"ProductImage": [
"The product image field is required."
]
} }
seems it gets only one array
You are passing the full request object instead of the values to your validator
Validator::make($request->all()...
You can validate arrays (of objects) using * like this
$validator = Validator::make($request->all(), [
'*.ProductTitle' => 'required',
'*.ProductColor' => 'required',
'*.ProductImage' => 'required'
]);
I'm trying to validate a json I'm getting via post, using the Dingo API library in Laravel. It seems that the validation is working incorrectly as I send a valid JSON according to the fields I am validating and it returns me the message saying:
The X field is required.
But I'm sending the X field in json, which I do not understand.
JSON:
[
{
"currency_id": 1,
"bills": [
{
"barcode": "99999.9999999.99999999.9999 9",
"due_date": "2018-09-14",
"value": 70.00
},
{
"barcode": "8888.888888.88888.8888 8",
"due_date": "2018-09-15",
"value": 32.00
}
]
}
]
I'm getting this error:
"message": "422 Unprocessable Entity",
"errors": {
"currency_id": [
"The currency id field is required."
],
"bills": [
"The bills field is required."
]
},
This is my custom FormRequest with validation rules, where I pass it as a parameter in the BillController store method.
namespace App\Http\Requests;
use App\Rules\Sum;
use Dingo\Api\Http\FormRequest;
class BillRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'currency_id' => 'required|integer|exists:currency,id',
'bills' => ['required', 'array', 'min:1', 'max:3', new Sum],
'bills.*.barcode' => 'required|string|min:10|max:255',
'bills.*.due_date' => 'date',
'bills.*.value' => 'required|numeric|between:10,30000',
];
}
}
To solve I had to put *. in front of each rule, as I'm getting an array the validator only understands this way.
public function rules()
{
return [
'*.currency_id' => 'required|integer|exists:currency,id',
'*.bills' => ['required', 'array', 'min:1', 'max:3', new Sum],
'*.bills.*.barcode' => 'required|string|min:10|max:255',
'*.bills.*.due_date' => 'date',
'*.bills.*.value' => 'required|numeric|between:10,30000',
];
}
My Request File rules are
public function rules()
{
return [
'mobile' => 'required',
'code' => 'required',
];
}
My input data can be a simple => for which the request validation is working fine.
{
"mobile":"81452569",
"code":"4858"
}
My input data can be a complex too => for which the request validation is not working fine.
[{
"mobile":"81452569",
"code":"4858"
},
{
"mobile":"81452570",
"code":"4858"
}]
How to validate for multiple rows with request.
I would sent it all in array to the request object like so:
"data" => [
[
"mobile" => "81452569",
"code" => "4858"
],
[
"mobile" =>"81452570",
"code" =>"4858"
]
];
Then in your validation rules do this:
public function rules()
{
return [
'data.*.mobile' => 'required',
'data.*.code' => 'required',
];
}