bizzabo / play-json-extensions Goto Github PK
View Code? Open in Web Editor NEW+22 field case class formatter and more for play-json
Home Page: http://cvogt.org/play-json-extensions/api/
License: Other
+22 field case class formatter and more for play-json
Home Page: http://cvogt.org/play-json-extensions/api/
License: Other
Do you plan a 2.12 version?
Play 2.5 macros use OFormat not Format.
Something like implicit val sampleFormt = Jsonx.formatCaseClass[Sample]
will compile but fail at runtime to do any conversions.
I have a slick codegen that I want to json.toJson for my results sets. Here is an example of a 22+ tuple
implicit def Table1Row(implicit e0: GR[String], e1: GR[Long], e2: GR[Option[String]]): GR[Table1Row] = GR{ prs => import prs._ <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[Long] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[String] :: <<[Long] :: <<[String] :: <<[String] :: <<?[String] :: HNil } /** Table description of table TABLE1. Objects of this class serve as prototypes for rows in queries. */ class Table1(_tableTag: Tag) extends Table[Table1Row](_tableTag, Some("Schema"), "TABLE1") { def * = x1 :: x2 :: x3 :: x4 :: x5 :: x6 :: x7 :: x8 :: x9 :: x10 :: x11 :: x12 :: x13 :: x14 :: x15 :: x16 :: x17 :: x18 :: x19 :: x20 :: x21 :: x22 :: x23 :: x24 :: x25 :: x26 :: x27 :: x28 :: x29 :: x30 :: x31 :: x32 :: x33 :: x34 :: x35 :: x36 :: x37 :: x38 :: x39 :: x40 :: x41 :: x42 :: x43 :: x44 :: x45 :: x46 :: x47 :: x48 :: x49 :: x50 :: x51 :: x52 :: x53 :: x54 :: HNil
Is there any way to render this as Json using the extension?
Eg:
Json.parse("""{"i": 5, "s":"foo", "type": "X"}""").as[SomeAdt] == X(5,"foo")
but it's neither obeyed during parsing, nor included when formatting.
if writers are running a newer version of a schema than readers, and writers add additional cases to a sealed structure,then readers can fail because of unexpected cases. Here is a pattern to solve this, which could be encoded as a another formatX method. This is for basically enums and would need to be changed
sealed abstract class All
sealed abstract class Known
object All {
final case class Unknown( value: JsValue ) extends All
case object Case1 extends Known
case object Case2 extends Known
import org.cvogt.play.json.SingletonEncoder.simpleNameUpperCase
import org.cvogt.play.json.implicits.formatSingleton
implicit def jsonFormat: Format[All] = new Format[All] {
private val formatKnown = Jsonx.formatSealed[Known]
def reads( json: JsValue ): JsResult[All] =
formatKnown.reads( json ) orElse JsSuccess( Unknown(json) )
def writes( o: All ): JsValue = o match {
case Unknown(json) => json
case known: Known => formatKnown.writes( known )
}
}
}
a simple example are case classes with all optional fields... anything can deserialize to them given play-jsons strategy to ignore additional fields
generalize:
implicit class FormatTagExtension[T](enclosed: Format[T]){
def tagWithType(implicit classTag: ClassTag[T]): Format[T] = new Format[T]{
def reads(jsValue: JsValue): JsResult[T] = {
val className = classTag.runtimeClass.getSimpleName
jsValue\"type" match {
case x: JsDefined => x.value.validate[String].filter(_ == className).flatMap(_ => enclosed.reads(jsValue))
case other => JsError(s"tagWithType cannot deserialize json without a matching type field. Found: " + jsValue)
}
}
def writes(value: T): JsValue = {
val className = classTag.runtimeClass.getSimpleName
enclosed.writes(value) match{
case x: JsObject => x ++ JsObject(Map("type" -> JsString(className)))
case other => throw new Exception(s"Cannot use tagWithType on Format[$className], because writes didn't return a JsObject but: " + other + " for " + value)
}
}
}
}
Is there any way to automatically convert camel case fields to underscored?
For example:
case case Person(firstName: String, lastName: String)
object Person {
// will be used by format to map field names
implicit val jsonConfig = JsonConfiguration(SnakeCase)
implicit val format = Jsonx.formatCaseClass[Person]
}
Should produce:
{
"first_name": "...",
"last_name": "..."
}
I found some code in ai.x.play.json.SingletonEncoder
but seems that it is used only in ai.x.play.json.Jsonx#formatSingleton
When I use jsonx and joda time in a case class.
import ai.x.play.json.Jsonx
import org.joda.time.DateTime
// case class
case class A (var a: Option[DateTime] = None)
// json object
object A { implicit val a = Jsonx.formatCaseClass[A]}
I also use slickless
and shapeless
to resolve the 22 params.
It throws the error:
could not find implicit value for parameter helper: play.api.libs.json.Reads[Option[org.joda.time.DateTime]]
TRIGGERED BY: could not find implicit value for parameter helper: ai.x.play.json.OptionValidationDispatcher[Option[org.joda.time.DateTime]]
TO SOLVE THIS
1. Make sure there is a Reads[Option[org.joda.time.DateTime]] or Format[Option[org.joda.time.DateTime]] in the implicit scope
2. In case of Reads[Option[...]] you need to either
import ai.x.play.json.implicits.optionWithNull // suggested
or
import ai.x.play.json.implicits.optionNoError // buggy play-json 2.3 behavior
3. In case of Reads[... .type]
import ai.x.play.json.SingletonEncoder.simpleName
import ai.x.play.json.implicits.formatSingleton
Is it possible to make OptionValidationDispatcher
constructor public? I need to implement a format for a case class with optional fields and want to tweak the logic that sets fields to None
. I want to have None
both when field is not found in JSON and when it is found but e.g. equals ""
. I cannot find other ways of implementing this except instantiating my own OptionValidationDispatcher
passing a custom function that works with LookupResult.
Can you please include the encoder import?
import ai.x.play.json.Encoders._.
In the Create explicit formatter section of you documentation.
On Maven Central, there is a version 0.14.0 published for this project; however, this GitHub repo does not contain a release, tag, or branch for 0.14.0, and the build.sbt
on master
has the version 0.10.0. Is the version on Maven Central legitimate?
there are two failure modes, one is a stack overflow, one is a match error. seems to depend on the order of the trait and the child classes in the code
[error] could not find implicit value for parameter helper: play.api.libs.json.Reads[SomeClassForWhichThereIsNotFormatter]
[error] TRIGGERED BY
[error] could not find implicit value for parameter helper: org.cvogt.play.json.OptionValidationDispatcher[SomeClassForWhichThereIsNotFormatter]
[error] TO SOLVE THIS
[error] import org.cvogt.play.json.implicits.optionWithNull // suggested
[error] or
[error] import org.cvogt.play.json.implicits.optionNoError // buggy play-json 2.3 behavior
[error] implicit def jsonFormat: Format[SomeClassThatHasTheOtherClassAsAField] = Jsonx.formatAdt[SomeClassThatHasTheOtherClassAsAField]( AdtEncoder.TypeAsField )
[error] ^
[error] one error found
[error] (models/compile:compileIncremental) Compilation failed
[error] Total time: 6 s, completed 06.08.2015 19:12:29
As a user, I want to ability to get JSON format for a case class using generic type.
Given
trait SomeTrait
case class ClassA(a:String, b:String) extends SomeTrait
case class ClassB(a:String) extends SomeTrait
case class CompositeClass[A <: SomeTrait](name:String,generics:A)
object ClassA {
implicit val classAJsonFormat = Jsonx.formatCaseClass[ClassA]
}
object ClassB {
implicit val classBJsonFormat = Jsonx.formatCaseClass[ClassB]
}
object CompositeClass {
implicit def compositeClassJsonFormat[A](implicit aft:OFormat[A]) = Jsonx.formatCaseClass[CompositeClass[A]]
}
Expected behaviour
No compilation and runtime error
Current behaviour
Error:(17, 107) could not find implicit value for parameter helper: play.api.libs.json.Reads[A]
TRIGGERED BY: could not find implicit value for parameter helper: ai.x.play.json.OptionValidationDispatcher[A]
TO SOLVE THIS
1. Make sure there is a Reads[A] or Format[A] in the implicit scope
2. In case of Reads[Option[...]] you need to either
import ai.x.play.json.implicits.optionWithNull // suggested
or
import ai.x.play.json.implicits.optionNoError // buggy play-json 2.3 behavior
3. In case of Reads[... .type]
import ai.x.play.json.SingletonEncoder.simpleName
import ai.x.play.json.implicits.formatSingleton
implicit def reads[A <: SomeTrait](implicit format: Format[A]): OFormat[CompositeClass[A]] = Jsonx.formatCaseClass[CompositeClass[A]]
Play Json is now at 2.6.0-M6 and about to be released. It also natively supports default values using a syntax like this:
implict val jsonFormat = Json.using[Json.WithDefaultValues].format[MyCaseClass]
However, there is still not support for 22+ fields.
Any anticipated date to support 2.6.x?
After upgrading to 0.40.2 it stopped working. I'm using Play 2.7.3. Version 0.30.1 worked just fine.
This is the error I get:
Image.scala:13:81: not found: value JsSuccess [error] implicit lazy val jsonFormat: OFormat[Image] = Jsonx.formatCaseClassUseDefaults[Image]
case class Image(url: String,
size: Option[Size] = None,
owned: Boolean = false,
thumbnails: List[Image] = List())
object Image {
implicit lazy val jsonFormat: OFormat[Image] = Jsonx.formatCaseClassUseDefaults[Image]
}
case class Size(width: Int,
height: Int)
object Size {
implicit lazy val jsonFormat: OFormat[Size] = Jsonx.formatCaseClassUseDefaults[Size]
}
Hi,
When I try make something likes it:
class Version(version_id: Int = Int.MinValue, completed: Boolean)
object Version {
implicit val versionFormat = Jsonx.formatCaseClassUseDefaults[Version]
}
I have error message that can help understand what happens:
[error] implicit val versionFormat = Jsonx.formatCaseClassUseDefaults[Version]
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
I think it is better then an error message said that formatCaseClassUseDefaults expect only case class ;)
Is there any way to write None values as null?
With play.api.libs.json.Json, I could do this:
case class Reason(name: String, flag: Option[Boolean])
implicit val conf = JsonConfiguration(optionHandlers = OptionHandlers.WritesNull)
implicit val jsonFormat = Json.format[Reason]
This would emit null for "flag" if the value is None.
Is something similar available for use with Jsonx.formatCaseClass invocation?
Hello,
On the README it's advertised that the current version available for Play 2.8 is version 0.41.0:
libraryDependencies += "ai.x" %% "play-json-extensions" % "0.41.0"
But the dependency can't be found by sbt, so is it released yet ?
Thanks
This one http://www.cvogt.org/play-json-extensions/api/ returns 404
I have a question regarding how optional fields are handled.
If I define a case class with an optional field using Jsonx.formatCaseClass
, I end with with nulls
when setting the field to None
and converting to json. However, using play's Json.format
, the field that is None
is not present in the resulting json.
Please see below for an example.
I am wondering if this is the desired behaviour. Thanks!
Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_31).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class Foo(
_1:Option[Int],_2:Option[Int],_3:Option[Int],_4:Int,_5:Int,
_21:Int,_22:Int,_23:Int,_24:Int,_25:Int,
_31:Int,_32:Int,_33:Int,_34:Int,_35:Int,
_41:Int,_42:Int,_43:Int,_44:Int,_45:Int,
_51:Int,_52:Int,_53:Int,_54:Int,_55:Int
)
val foo = Foo(None,None,Some(3),4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5)
import org.cvogt.play.json.Jsonx
implicit def jsonFormat = Jsonx.formatCaseClass[Foo]
import play.api.libs.json.Json
println(Json.prettyPrint(Json.toJson(foo)))
// Exiting paste mode, now interpreting.
{
"_1" : null,
"_2" : null,
"_3" : 3,
"_4" : 4,
"_5" : 5,
"_21" : 1,
"_22" : 2,
"_23" : 3,
"_24" : 4,
"_25" : 5,
"_31" : 1,
"_32" : 2,
"_33" : 3,
"_34" : 4,
"_35" : 5,
"_41" : 1,
"_42" : 2,
"_43" : 3,
"_44" : 4,
"_45" : 5,
"_51" : 1,
"_52" : 2,
"_53" : 3,
"_54" : 4,
"_55" : 5
}
defined class Foo
foo: Foo = Foo(None,None,Some(3),4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5)
import org.cvogt.play.json.Jsonx
jsonFormat: play.api.libs.json.Format[Foo]
import play.api.libs.json.Json
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class Bar(
_1:Option[Int],_2:Option[Int],_3:Option[Int],_4:Int,_5:Int
)
val bar = Bar(None,None,Some(3),4,5)
import play.api.libs.json.Json
implicit def jsonFormat = Json.format[Bar]
println(Json.prettyPrint(Json.toJson(bar)))
// Exiting paste mode, now interpreting.
{
"_3" : 3,
"_4" : 4,
"_5" : 5
}
defined class Bar
bar: Bar = Bar(None,None,Some(3),4,5)
import play.api.libs.json.Json
jsonFormat: play.api.libs.json.OFormat[Bar]
scala>
JsonFormat macro annotation for lazy people
instead of
case class X(v: String)
object X {
implicit lazy val format = Json.format[X]
}
just do:
@JsonFormat
case class X(v: String)
If one uses backticks in case classes like case class Header(`Content-Type`: String)
a compiler error occurs like: Error:value Content-Type is not a member of ....Header implicit lazy val jsonFormat: OFormat[Header] = Jsonx.formatCaseClass[Header]
We've been using this library in combination with require
to constrain our domain objects, but still get nice JsError
s back.
Unfortunately this does not work with Jsonx.formatInline
case class PositiveInteger(i: Int) {
require(i >= 1, "Number must be a positive integer")
}
import play.api.libs.json.Json
// JsError(ValidationError("Number must be a positive integer"))
Jsonx.formatCaseClass[PositiveInteger].reads(Json.parse("""{ "i": -1 }""")))
// IllegalArgumentException("Number must be a positive integer") gets thrown
Jsonx.formatInline[PositiveInteger].reads(Json.parse("-1")))
I might be able to create a PR for this friday if this is wanted
Hi, I had problems trying use 0.8.0 version in Play 2.4.8.
in fact, this compile, but does not execute. I had this exception:
[info] - play.api.Play - Application started (Dev)
[error] - akka.actor.ActorSystemImpl - Uncaught fatal error from thread [application-akka.actor.default-dispatcher-6] shutting down ActorSystem [application]
java.lang.NoSuchMethodError: play.api.libs.iteratee.Execution$Implicits$.trampoline()Lscala/concurrent/ExecutionContext;
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$9.apply(PlayDefaultUpstreamHandler.scala:159) ~[play-netty-server_2.11-2.4.8.jar:2.4.8]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$9.apply(PlayDefaultUpstreamHandler.scala:157) ~[play-netty-server_2.11-2.4.8.jar:2.4.8]
at play.api.mvc.EssentialAction$$anon$2.apply(Action.scala:55) ~[play_2.11-2.4.8.jar:2.4.8]
at play.api.mvc.EssentialAction$$anon$2.apply(Action.scala:54) ~[play_2.11-2.4.8.jar:2.4.8]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$15.apply(PlayDefaultUpstreamHandler.scala:210) ~[play-netty-server_2.11-2.4.8.jar:2.4.8]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$15.apply(PlayDefaultUpstreamHandler.scala:210) ~[play-netty-server_2.11-2.4.8.jar:2.4.8]
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) ~[scala-library-2.11.8.jar:na]
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) ~[scala-library-2.11.8.jar:na]
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40) ~[akka-actor_2.11-2.3.13.jar:na]
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397) [akka-actor_2.11-2.3.13.jar:na]
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [scala-library-2.11.8.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [scala-library-2.11.8.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [scala-library-2.11.8.jar:na]
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [scala-library-2.11.8.jar:na]
[error] - play.core.server.netty.PlayDefaultUpstreamHandler - Exception caught in Netty
java.lang.NoSuchMethodError: play.api.libs.iteratee.Execution$Implicits$.trampoline()Lscala/concurrent/ExecutionContext;
at play.core.server.netty.PlayDefaultUpstreamHandler.play$core$server$netty$PlayDefaultUpstreamHandler$$handleAction$1(PlayDefaultUpstreamHandler.scala:270) ~[play-netty-server_2.11-2.4.8.jar:2.4.8]
at play.core.server.netty.PlayDefaultUpstreamHandler.messageReceived(PlayDefaultUpstreamHandler.scala:166) ~[play-netty-server_2.11-2.4.8.jar:2.4.8]
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.handler.timeout.IdleStateAwareChannelUpstreamHandler.handleUpstream(IdleStateAwareChannelUpstreamHandler.java:36) ~[netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791) [netty-3.10.5.Final.jar:na]
at com.typesafe.netty.http.pipelining.HttpPipeliningHandler.messageReceived(HttpPipeliningHandler.java:62) [netty-http-pipelining-1.1.4.jar:na]
at org.jboss.netty.channel.SimpleChannelHandler.handleUpstream(SimpleChannelHandler.java:88) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:108) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:459) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:536) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:435) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:108) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:337) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108) [netty-3.10.5.Final.jar:na]
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42) [netty-3.10.5.Final.jar:na]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_91]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91]
So, I want ask if could you remove "... seem very compatible"?
Thank you!
I wrote this code
{
case class Foo(accountNumber: String)
object Foo {
implicit val config = JsonConfiguration(SnakeCase)
import ai.x.play.json.Jsonx
implicit lazy val jsonFormat = Jsonx.formatCaseClass[Foo]
}
}
Json.parse("""{"account_number":"a"}""").validate[Foo]
If I was not using Play Json extensions, it would have parsed account_number to accountNumber. but with the extensions (in code above). it fails
res11: JsResult[Foo] = JsError(
List((JsPath(List(KeyPathNode("accountNumber"))), List(JsonValidationError(List("error.path.missing"), WrappedArray()))))
)
I've noticed a different behavior between jsonx
format and standard json format when dealing with Option fields. In the example below, the first fromJson
conversion returns a JsError
while the second call returns JsSuccess
. In my opinion the first behavior is the correct one since the JSON object is invalid.
This is relative to version 0.2. I know it is quite old, but if you could provide any clue on how to fix it I would really appreciate it :)
import org.cvogt.play.json.Jsonx
import play.api.libs.json._
case class C1(v: Option[String])
case class C2(v: Option[String])
implicit val c1JsonFormat = Json.format[C1]
implicit val c2JsonFormat = Jsonx.formatCaseClass[C2]
val json = Json.obj("v" -> 11)
Json.fromJson[C1](json) // this returns JsError
Json.fromJson[C2](json) // this returns JsSuccess
Thanks
For classes where these libraries overlap, does play-json-extensions
produce and read the same output as play-json
? Is it supposed to?
e.g.
case class Foo(bar: String, baz: Int)
object Foo {
val jsonFormat: OFormat[Foo] = Json.format[Foo]
val jsonxFormat: OFormat[Foo] = Jsonx.formatCaseClassUseDefaults[Foo]
val foo: Foo = Foo("ab", 1)
val fooVal: JsValue = ...
assert(jsonFormat.writes(foo) == jsonxFormat.writes(foo))
assert(jsonFormat.reads(foo) == jsonxFormat.reads(foo))
}
This project hasn't been build on CircleCI since dec 20th, 2018.
The project has valid CircleCI v2 configuration, so re-enabling is very simple.
A maintainer can do this by going to https://circleci.com/setup-project/gh/xdotai/play-json-extensions and pressing the "Start building" button
needs these imports, but doesn't say so:
import SingletonEncoder.simpleName // required for formatSingleton
import org.cvogt.play.json.implicits.formatSingleton // required if trait has object children
subj
When I checkout the master and change
"com.typesafe.play" %% "play-json" % "2.3.4",
to
"com.typesafe.play" %% "play-json" % "2.4.0-RC1",
and test.
But it compile failed.
[error] ******/play-json-extensions-0.2/src/test/scala/CaseClassTest.scala:45: No Json deserializer found for type Option[String]. Try to implement an implicit Reads or Format for this type.
[error] Error occurred in an application involving default arguments.
[error] implicit def fmt1 = Jsonx.formatCaseClass[Bar]
[error] ^
[error] one error found
[error] (test:compile) Compilation failed
[error] Total time: 4 s, completed 2015-5-1 17:06:27
And in play-json 2.3.8 it builds successed.
i.e. hard to find out whats wrong
Good day!
I try create a format for generic case class. I have a code:
case class Page[T](offset: Int, limit: Int, values: List[T] = List())
case class Document(document_id: Int = Int.MinValue, name: String)
object Document {
implicit val documentFormat = Jsonx.formatCaseClassUseDefaults[Document]
implicit val documentPageFormat = Jsonx.formatCaseClassUseDefaults[Page[Document]]
}
When I try to compile it I have an error:
could not find implicit value for parameter helper: play.api.libs.json.Reads[List[T]]
TRIGGERED BY: could not find implicit value for parameter helper: ai.x.play.json.OptionValidationDispatcher[List[T]]
TO SOLVE THIS
1. Make sure there is a Reads[List[T]] or Format[List[T]] in the implicit scope
2. In case of Reads[Option[...]] you need to either
import ai.x.play.json.implicits.optionWithNull // suggested
or
import ai.x.play.json.implicits.optionNoError // buggy play-json 2.3 behavior
3. In case of Reads[... .type]
import ai.x.play.json.SingletonEncoder.simpleName
import ai.x.play.json.implicits.formatSingleton
How can I solve it?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.