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?
2
Answers
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
isnull
, or similar.Give this a shot:
Using that, you’ll get something like this:
Your
$rules
array can get pretty large, depending on the number ofshapes
being uploaded, but this should allow you to explicitly target certain validation rules for each shape, depending on thetype
supplied.Just pass the array element in and then implement the type check in your rule:
Then, in the rule, the
$value
will contain the type and the coordinates.