I am trying to display json data from database using scala/anorm of Play(2.2.x), If I give the following trial, I am getting the error like: type mismatch; found : scala.collection.immutable.Stream[String] required: String
, but If I write like: sql().map(row => rowString).toString - is giving Stream type json data(i don't need it), so how can I get my normal json data for it ? Please help me and thank in advance.
contorller:
class Test extends Controller {
def getTest = Action {
var sql: SqlQuery = SQL("select name::TEXT from test");
def values: String = DB.withConnection { implicit connection =>
sql().map(row => row[String]("name"))//giving error: type mismatch; found : scala.collection.immutable.Stream[String] required: String
}
Ok(values)
}
It looks like you are using Anorm for database access. As noted in the comments above, executing the Anorm query returns a Stream
rather than just a value. When you map the value, it is again returning a Stream
of String
so that the results can be processed as a stream. This is very useful for large result sets where it makes more sense to process the stream incrementally and stream the result to the client. It looks like you are just getting started so you probably don't want to worry about that right now.
You can covert the result from a stream into a conventional list by simply using toList
:
val resList = sql().map(row => row[String]("name")).toList
Now, you also need to unescape the string and return it as a JSON result. That can be done by using string interpolations. To do this, you just need to surround the String
in a StringContext
and call the s
method with no arguments.
val newResList = resList.map(s => StringContext(s).s())
Finally, you should actually be converting the String into a PlayJson JsValue type so that your controller is actually returning the right type.
Json.parse(newResList.mkString("[",",","]")
The mkString
method is used to convert the list into a valid JSON string. You will need to import play.api.libs.json.Json
for this to work. Passing a JsValue
to Ok
ensures that the mime type of the response is set to "application/json". You can learn more about using JSON with play here. This will be important if you intend to build JSON services.
Putting it together, you get the following:
class Test extends Controller {
def getTest = Action {
var sql: SqlQuery = SQL("select name::TEXT from test");
def values: JsValue = DB.withConnection { implicit connection =>
val resList = sql().map(row => row[String]("name")).toList
val newResList = resList.map(s => StringContext(s).s())
Json.parse(newResList.mkString("[",",","]")
}
Ok(values)
}
You could also use the following alternate structure to simplify and get rid of the rather sloppy mkString
call.
class Test extends Controller {
def getTest = Action {
var sql: SqlQuery = SQL("select name::TEXT from test");
def values: JsValue = DB.withConnection { implicit connection =>
val resList = sql().map(row => row[String]("name")).toList
Json.toJson(resList.map(s => Json.parse(StringContext(s).s())))
}
Ok(values)
}
This parses each of the JSON strings in the list and then converts the list into JsArray
again using the capabilities of Play's built in JSON library.