Frage

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)

War es hilfreich?

Lösung

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top