Reputation: 32756
I'm new to Scala and I'm trying to figure out how I would add a key/value to a JsValue. In JavaScript you might do something like SomeObject.newKey = newValue
. Here's my real use case:
def doAccountUpdate(account: db.models.Account, config: JsObject, job: JsValue) : JsValue = {
val passwordParam = (job \ "params" \ "password")
if (passwordParam.toOption.isDefined) {
val password = (job \ "params" \ "password").get.as[String]
val encrypted_password = Auth.passwordEncrypt(password)
// ADD `encrypted_password`'s value TO `job \ params` so its `job \ params \ encryptedPassword`
}
Account.update(account, config, job)
}
Account.update
actually updates the DB so in my doAccountUpdate
i'm prepping the data. One of those items I need to prep is password by encrypting it before passing it to Account.update
. How do I do this?
EDIT
To explain why the question this is marked a duplicate of doesn't work for me is this is their example:
jsonObject.as[JsObject] + ("c" -> Json.toJson(3))
If I duplicate that in my code it would look like this:
updateJob = job.as[JsObject] + ("encryptedPassword" -> Json.toJson(encrypted_password))
but that outputs:
{
"id":"...",
"params": {
"password":"Programmer2!"
},
"encryptedPassword":"$2a$10$EHnJHXh1sTORxliPocWfDuHnlRzu1YwG.kyBee.u85apCXTuLij.y"
}
Note how encryptedPassword
isn't in params
Upvotes: 0
Views: 2804
Reputation: 8901
As @danielnixon suggests, you can use JSON transformers for this. Here is an example:
val encryptPassword: Reads[JsObject] = (__ \ "params").json.update(
(__ \ "password").read[String].flatMap(pw =>
(__ \ "encryptedPassword").json.put(JsString(Auth.passwordEncrypt(pw)))
)
)
This says we will:
params
objectencryptedPassword
branch in the params
objectWhen you apply that with job.transform(encryptPassword)
you'll get a JsResult
that, if the params object exists and has a password
field with a string value, will be JsSuccess
- otherwise you'll get JsError
. You can handle that with something like the following:
def doAccountUpdate(account: db.models.Account, config: JsObject, job: JsValue) : JsValue = {
job.transform(encryptPassword) match {
case JsSuccess(newJob, _) => Account.update(account, config, newJob)
case JsError(errors) => sys.error("No password supplied!")
}
}
Upvotes: 1