Basically what I want to achieve is simply to execute a MongoDB query using Casbah in a Play Framework 2.2 controller, pass the result(s) to a view and present the result(s) in HTML.
I think my main problem is, I don't know how to define the parameters of the view, because the view doesn't know any of the result types I tried and a @import
in the line below doesn't seem to help either.
Controller action:
def read = Action {
val mongoClient = MongoClient("localhost", 27017)
val db = mongoClient("sampleapp")
val coll = db("testcoll1")
// Query: get all documents
val docs = coll.find() // Type: coll.CursorType
val list = docs.toList
Ok(views.html.casbahsamples.read(list))
}
As you can see, I try to convert the result to a List
, because docs
seems to be of type coll.CursorType
where coll
is the name of my value and when it's passed to the view I don't have a clue how to use this in the parameter line because the compiler asks for type coll.CursorType
but doesn't even know about coll
.
Anyway, if I declare the type List[Any]
for my list parameter in the view, this will partly work, but I won't be able to access any properties of the result documents, because none of the methods work on objects of type Any
.
I think, the best way would be to declare List[BasicDBObject]
in the view's parameter line, but BasicDBObject
is not a known type. So I tried to import it in the line below (as far as I know that's the only place in a view where imports are allowed). But this doesn't change anything.
View:
@(list: List[BasicDBObject])
@import com.mongodb.BasicDBObject
@* also tried:
@import com.mongodb.casbah.Imports._
*@
<h2>Query results</h2>
<h3>Number of query results:</h3>
<p>@list.length</p>
<h3>Results:</h3>
<code>@list</code><!-- this will be a JSON string representation, but that's not what I want -->
<h4>List:</h4>
@import java.math.BigInteger; var i = 0;
@for(doc <- list) {
@{i += 1; i}:<br>
@*
doc is of type BasicDBObject as I found out doing this:
@doc.asInstanceOf[AnyRef].getClass.getSimpleName
*@
@doc
@* The next line results in a compilation error: value filter is not a member of Any *@
@defining(doc.filter(_.isInstanceOf[BasicDBObject]).map(_.asInstanceOf[BasicDBObject])) { docX =>
@docX.asInstanceOf[AnyRef].getClass.getSimpleName
}
<br><br>
<dl style="background: #ccc">
<dt>_id</dt>
@* doc will be of type BasicDBObject *@
@* <dd>@doc.getString("pie")</dd> *@
@* <dd>@docX.getString("pie")</dd> *@
</dl>
<br><br>
}
My attempt to convert Any
to BasicDBObject
does not work, because the compiler says filter
and map
are not members of Any
.
What do I have to do to use/access/display the results of my query in a view?
(BTW: The full code is on GitHub)
The answer to this is so simple, I can't believe I didn't have this idea earlier...
I just had to add the full package name in the first line of the view...
@(list: List[com.mongodb.casbah.Imports.DBObject])
..and then I don't even have to import the package. I can now display each attribute value of a document separately with e.g. @doc.get("_id")
.
Should anybody be interested, here's the full view file.