Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel validate array of object JSON

I have a POST endpoint on my Laravel 5.5 API, I used postman to test my route and here is the problem. I want to send an array of the same kind of object, like this:

[
  { 
   "name":"test",
   "tag":"TEST"
  },
  {
   "name":"test2",
   "tag":"TEST_2"
  }
]

But I can't manage to validate it properly.

in my controller, I have this:

$validator = Validator::make($requests->all(), [
 
   'name' => 'required|string',
   'tag' => 'required|string'
]);

if($validator->fails()) 
   //Warn user for errors 

I also tried with the simple

$this->validate($requests->all() .... )

I tried renaming the rules with '.name' and '*.name' but no success.

I tried replacing $request->all() with $request->input()but no success.

I also tried to loop over it but I get exceptions

foreach($request as $req){

  $validator = Validator::make($req ....) 

  //rest of the code
}

On the other hand, I can retrieve the data like this $datas = $request->all() and store them but there is no validation.

The only solution that seems to be working is naming my array:

{
 "data" : [
      { 
       "name":"test",
       "tag":"TEST"
      },
      {
       "name":"test2",
       "tag":"TEST_2"
      }
    ]
}

And then name the rules with 'data.*.name' but this obliges the API user to parse the array. Let suppose I have an array $array which I want to store, I need to do

$arrayParsed = ['data' => $array]

and call the API with $arrayParsed, which I think is a little redundant.

Is there a better way to handle the problem?

like image 966
Irindul Avatar asked Sep 14 '17 14:09

Irindul


People also ask

How to validate form array in Laravel?

To validate a set of objects or the data in an array, Laravel avails of validation options of various kinds. You can consider all the options that are made available before finally sticking on to one of the options. Form array validation is one such process.

What are the benefits of ‘validation’ in Laravel?

Also, the benefit of creating a new rule and customizing it as per the needs is possible in ‘validation’ in Laravel. There are array-based forms that can be generated in Laravel and they are not a pain to be generated. The ‘dot notification’ can be used by the user to validate the attributes that are present within an array.

What is @JSON error in Laravel?

JSON API errors will be included containing the Laravel validation messages in the detail member of the error object. Each error will also have a JSON source point set identifying the location in the request content of the validation failure. Validators are provided with the resource fields that were submitted by the client.

How to validate boolean values in Laravel?

In JSON, a boolean is always true or false. However Laravel's boolean validation rule is loosely typed - i.e. it will accept true, false, 0 , 1, "0", and "1" as valid values. For JSON it is better to by strictly typed for boolean values.


2 Answers

The approved answer works if your posting an array, however to take it a step further, I am needing to save multiple arrays. While that approach would work if I make two separate endpoints, what if I want to save everything inside one DB::transaction?

Viola:

POST:

{
"array1": [
    { "key1": "string", "key2": 1 },
    { "key1": "string", key2": 0 }
  ],
"array2": [
    { "key3": "string", "key4": 1 },
    { "key3": "string", "key4": 0 }
  ]
}

SERVER:

$this->validate($request, [
    'array1' => 'present|array',
    'array2' => 'present|array',
    'array1.*.key1' => 'required|string',
    'array1.*.key2' => 'required|integer',
    'array2.*.key3' => 'required|string',
    'array2.*.key4' => 'required|integer'
]);

DB::transaction(function() use($request) {
    foreach($request['array1'] as $x){
        ...do stuff here
    };
});

Note: 'present|array' accepts empty arrays whereas 'required|array' would reject them.

like image 163
Michael Aaron Wilson Avatar answered Sep 28 '22 22:09

Michael Aaron Wilson


You can try to circumvent the issue by first doing:

$data = [ 'data' => $requests->all() ];

Then you can use the rule you suggested:

$validator = Validator::make($data, [
   'data.*.name' => 'required|string',
   'data.*.' => 'required|string'
]);

Not the most elegant solution but it solves your issue...

like image 20
Niraj Shah Avatar answered Sep 28 '22 23:09

Niraj Shah