custom date format in JSON for DateTimeField with mongorecord

496 views
Skip to first unread message

magegu

unread,
Jul 17, 2012, 12:15:34 PM7/17/12
to lif...@googlegroups.com

hy guys!

im using lift-mongodb-record 2.4. All of my MongoRecord models include the following DateTimeFieldfield, eg:

object created_at extends DateTimeField(this)

when i call asJSON on this model, it'll parse the date into a string e.g.

Mon, 16 Jul 2012 21:26:58 GMT

I would prefer other formats (eg. ISO 8601, depends on the acutal use-case)

how and where would I set up a custom format?

thanks

Tim Nelson

unread,
Jul 17, 2012, 3:22:08 PM7/17/12
to lif...@googlegroups.com
Hi,

If you use asJsExp (this in turn calls asJValue, which uses lift-json and not the older lift-util json parser) instead of asJSON, you can control the format by overriding formats in your Record. I think it uses ISO 8601 by default, though.

Tim

Diego Medina

unread,
Jul 17, 2012, 3:45:36 PM7/17/12
to lif...@googlegroups.com
@Tim: should we deprecate asJSON ? I haven't looked much at the Mongo
stuff, but today I noticed you said twice that asJSON uses the old
JSON parser.

Thanks

Diego
> --
> Lift, the simply functional web framework: http://liftweb.net
> Code: http://github.com/lift
> Discussion: http://groups.google.com/group/liftweb
> Stuck? Help us help you:
> https://www.assembla.com/wiki/show/liftweb/Posting_example_code



--
Diego Medina
Lift/Scala Developer
di...@fmpwizard.com
http://www.fmpwizard.com

magegu

unread,
Jul 18, 2012, 7:41:52 AM7/18/12
to lif...@googlegroups.com
Hi Tim,
thanks again for helping me out! I think i need to clarify some more broader facts to really get how to deal with mongorecord and the date stuff.
Could you maybe approve the following code-snippets and check if i'm using mongorecord correctly?

1.) i'm not using lift as a framework but scalatra - so i'll create an object using the following syntax, is that correct?

val json:JValue = parse(request.body)

var artifact = Artifact.fromJValue(json).get

artifact.save

2.) i've to manually set artifact.deleted_at(None)  otherwise I'll contain the current date (also for updates), how could i prevent this?

3.) i'm using the save method to update a model - can I whitelist certain attributes, that can be updated but some cannot after creation?

4.) to receive items, i'm using Rogue and the following snippet which is working really nice! but i'll still give back created_at: "Wed, 18 Jul 2012 11:28:08 GMT" where i would like to have something like "1997-07-16T19:20+01:00" - any suggestion?

val artifacts = Artifact where (_.deleted_at exists false)

val jval = JArray(artifacts.map(x => x.asJValue))

halt(200, pretty(render(jval))) 


thank you for any support on this! so far it's been a pleasure to work with the lift project and it saved me a lot of time!

Tim Nelson

unread,
Jul 18, 2012, 8:23:04 AM7/18/12
to lif...@googlegroups.com
Hi,

See comments inline.


On Wednesday, July 18, 2012 6:41:52 AM UTC-5, magegu wrote:
Hi Tim,
thanks again for helping me out! I think i need to clarify some more broader facts to really get how to deal with mongorecord and the date stuff.
Could you maybe approve the following code-snippets and check if i'm using mongorecord correctly?

1.) i'm not using lift as a framework but scalatra - so i'll create an object using the following syntax, is that correct?

val json:JValue = parse(request.body)

var artifact = Artifact.fromJValue(json).get

artifact.save

This is fine conceptually, but the way you're dealing with Box is not safe. I would write it like this:

val artifact = Helpers.tryo(parse(request.body)).flatMap(json => Artifact.fromJValue(json)).map(_.save)
 

2.) i've to manually set artifact.deleted_at(None)  otherwise I'll contain the current date (also for updates), how could i prevent this?

Set optional_? = true for this field and it will not be set:

object created_at extends DateTimeField(this) {
  override def optional_? = true
}
 

3.) i'm using the save method to update a model - can I whitelist certain attributes, that can be updated but some cannot after creation?

Not that I'm aware of. But, if you don't modify anything, their values will not be changed, so I'm not sure why this would be needed.
 

4.) to receive items, i'm using Rogue and the following snippet which is working really nice! but i'll still give back created_at: "Wed, 18 Jul 2012 11:28:08 GMT" where i would like to have something like "1997-07-16T19:20+01:00" - any suggestion?

val artifacts = Artifact where (_.deleted_at exists false)

val jval = JArray(artifacts.map(x => x.asJValue))

halt(200, pretty(render(jval))) 


You can control the format of Dates by overriding formats on your MetaRecord:

object Artifact extends Artifact with MongoMetaRecord[Artifact] {
   override def formats = new DefaultFormats {
    override def dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") 
  } 
}

After looking at the Lift code, I just realized that probably won't work. formats are defined on MongoMetaRecord and not in MetaRecord, so they are not available in DateTimeField or any other Field defined in the Record package. You could use net.liftweb.mongo.record.field.DateField, but it uses java.util.Date, which is not optimal.

You could also override the asJValue function on your field:

object created_at extends DateTimeField(this) {
  override def optional_? = true
  override def asJValue: JValue = valueBox
    .map(v => JString(owner.meta.formats.dateFormat.format(v))) openOr (JNothing: JValue)
}

I will open a ticket that will move the formats up to MetaRecord and then use those formats when creating json via asJValue.

Tim Nelson

unread,
Jul 18, 2012, 8:29:43 AM7/18/12
to lif...@googlegroups.com
Hi Diego,

I would be +1 for deprecating asJSON and fromJSON, but this is a Record thing and not MongoRecord, so others would have to chime in.

For completeness sake, let me explain this as I believe I misspoke in one of the posts.

asJSON uses JsCmds to build the JSON, which is not so bad. The one advantage asJValue has is the use of lift-json formats, for customizing output, in particular Dates.

fromJSON uses the older util.JSONParser. It's not as performant (or so I've heard) as the lift-json parser. Plus with the lift-json parser you get formats as well as the ability to transform, filter, etc your json, if needed.

Tim

Diego Medina

unread,
Jul 18, 2012, 5:05:31 PM7/18/12
to lif...@googlegroups.com
Thanks for the explanation Tim,

I started a separate thread
https://groups.google.com/d/topic/liftweb/1eEQjR02Lf0/discussion
to see when the community thinks about deprecating the JsonParser.

Thanks

Diego

Martin Güther

unread,
Jul 18, 2012, 7:12:39 PM7/18/12
to lif...@googlegroups.com
Thank you so much, Tim!
Your feedback helped a lot and i can work way more effective now!
Hoping for a MetaRecord fix soon - but the workaround will do its job :)
> After looking at the Lift code, I just realized that probably won't work. formats are defined on MongoMetaRecord and not in MetaRecord, so they are not available in DateTimeField or any other Field defined in the Record package. You could use net.liftweb.mongo.record.field.DateField (http://web.mongo.record.field.DateField), but it uses java.util.Date, which is not optimal.
>
> You could also override the asJValue function on your field:
>
> object created_at extends DateTimeField(this) {
> override def optional_? = true
> override def asJValue: JValue = valueBox
> .map(v => JString(owner.meta.formats.dateFormat.format(v))) openOr (JNothing: JValue)
> }
>
>
> I will open a ticket that will move the formats up to MetaRecord and then use those formats when creating json via asJValue.
>
> >
> > thank you for any support on this! so far it's been a pleasure to work with the lift project and it saved me a lot of time!
> > Am Dienstag, 17. Juli 2012 21:22:08 UTC+2 schrieb Tim Nelson:
> > > Hi,
> > >
> > > If you use asJsExp (this in turn calls asJValue, which uses lift-json and not the older lift-util json parser) instead of asJSON, you can control the format by overriding formats in your Record. I think it uses ISO 8601 by default, though.
> > >
> > > Tim
> > >
> > > On Tuesday, July 17, 2012 11:15:34 AM UTC-5, magegu wrote:
> > > >
> > > >
> > > >
> > > >
> > > > hy guys!
> > > >
> > > >
> > > > im using lift-mongodb-record 2.4. All of my MongoRecord models include the following DateTimeFieldfield, eg:
> > > >
> > > >
> > > > object created_at extends DateTimeField(this)
> > > >
> > > >
> > > > when i call asJSON on this model, it'll parse the date into a string e.g.
> > > >
> > > >
> > > > Mon, 16 Jul 2012 21:26:58 GMT
> > > >
> > > >
> > > > I would prefer other formats (eg. ISO 8601, depends on the acutal use-case)
> > > >
> > > >
> > > > how and where would I set up a custom format?
> > > >
> > > >
> > > > thanks
>
>
>
Reply all
Reply to author
Forward
0 new messages