简体   繁体   中英

How can I automatically map JSON to a case class when a field is a scala keyword?

Within the Play Framework (2.6) ; I am currently automatically mapping JSON to case classes from MongoDB (using ReactiveMongo 0.12 with JSON Collections ). I have downloaded a dataset ( here ) and imported it into MongoDB as a collection in order to do some testing relating to geospatial queries . However one of the fields is called " type " (at a quick glance you will see this here ) so I am having issues as this is a keyword in Scala . This would otherwise be what I would write:

   case class Geometry(coordinates: List, type: String)
   case class Neighborhood(_id: Option[BSONObjectID], geometry: Geometry, name: String)

Many thanks for any suggestions here!

Just to add (thanks to @MarioGalic); declaring scala keywords as class parameter names seems to be done with backticks but I am still having an issue outputting these in the Play templates . So if I was looping through each document I might write this (which is getting an error).

   @for(ngh <- neighborhoods){
     <tr>
        ...
        <td>@ngh.name</td>
        <td>@ngh.geometry.`type`</td>
        ...
     </tr>
   }

Without backticks doesn't work here and with backticks aren't recognised within the template . I cannot find any other formats in this referenced question/answer on the subject so I am still having an issue. Thanks


Sorry this is obvious as to what to do. Within the case class model just define a method that has a different name (from "type" in this example but essentially any keyword which is causing an issue:

   case class Geometry(coordinates: List, `type`: String) {
      def getType = `type`
   }

Then call this in the template :

   @for(ngh <- neighborhoods){
     <tr>
        ...
        <td>@ngh.name</td>
        <td>@ngh.geometry.getType</td>
        ...
     </tr>
   }

Thanks all!

You could wrap the field type with backticks like so:

case class Geometry(coordinates: List, `type`: String)

The following answer explains backticks syntax in more detail: Need clarification on Scala literal identifiers (backticks)

Simply wrap your code in curly braces like this:

@{ngh.geometry.`type`}

and the type field will be properly rendered in the Play template. There is no need to create the getType method.

Your full working code would be:

@for(ngh <- neighborhoods){
   <tr>
     ...
     <td>@ngh.name</td>
     <td>@{ngh.geometry.`type`}</td>
     ...
   </tr>
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM