j3d
j3d

Reputation: 9734

Play Framework: How to validate a JSON array and ensure it contains at least one element

Given the following JSON...

{
  "recipients" : [
    "[email protected]", "[email protected]"
  ],
  "subject" : "My subject",
  "body" : "My body"
}

... I need to validate the recipient list... and here below is my code:

import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.libs.json.Reads._

val js = Json.parse("""{"subject":"My subject","body":"My body", "recipients":["[email protected]","[email protected]"]}""")

val validateRecipients = verifyingIf((arr: JsArray) =>
  arr.value.nonEmpty)(Reads.list(Reads.email))
val recipients: Reads[JsArray] = {
  (__ \ 'recipients).json.pick[JsArray] andThen validateRecipients
} 

val validateNotification = (
  ((__ \ 'recipients).json.copyFrom(recipients)) ~
  ((__ \ 'subject).json.pickBranch) ~
  ((__ \ 'body).json.pickBranch)
).reduce 

validateNotification.reads(js).fold(
  valid = { validated => JsSuccess(validated) },
  invalid = { errors => JsError(errors) }
)

The code above works as expected, i.e. each element in recipients is verified and in case of invalid email address a validation error is raised... but let's suppose a JSON snippet like this:

{
  "recipients" : [],
  "subject" : "My subject",
  "body" : "My body"
}

In this case no validation error is raised... but I need to ensure recipients contains at least one element. Ho do I enhance my validator to achieve this?

EDIT

Here below is the solution as suggested by bjfletcher:

val validateRecipients = verifyingIf((arr: JsArray) =>
  arr.value.nonEmpty)(Reads.list(Reads.email))
val recipients: Reads[JsArray] = {
  (__ \ 'recipients).json.pick[JsArray] andThen verifying[JsArray](_.value.nonEmpty) andThen validateRecipients
} 

I hope it helps.

Upvotes: 2

Views: 1083

Answers (1)

bjfletcher
bjfletcher

Reputation: 11518

You can and this in:

verifying[JsArray](_.value.length > 0)

Upvotes: 2

Related Questions