I'm trying to pass a book object from views to routes, and then send it to calculate in a controller. My code is following:
bookList.scala.html
@(books: java.lang.Iterable[Book])
@main("BookList"){
<div class="row">
@for(book <- books.iterator()){
<div class="col-sm-6 col-md-4">
<div class="thumbnail" style="height: 435px">
...
<p><a href="@routes.Application.buy(book)" class="btn btn-primary" role="button"
style="vertical-align:bottom">Order now!</a>
</div>
</div>
</div>
}
</div>
}
routes
...
GET /order controllers.Application.buy(book: models.Book)
...
However, It gave me an error : No QueryString binder found for type models.Book. Try to implement an implicit QueryStringBindable for this type.
I tried to change the routes as :
GET /order controllers.Application.buy(book)
It also returned an error :
type mismatch; found : String required: models.Book
That's not how Play routing works. The Play router parses variables from the URL or query string, and converts them to native types via the QueryBindable
typeclass. You should have something more like this:
routes
GET /order/:bookid controllers.Application.buy(bookid: String)
And the action should be like:
Application.scala
def buy(bookid: String) = Action { request =>
// Look up book by id here.
Ok(views.html.thanks("you bought a book!"))
}
And the template like this:
bookList.scala.html
@for(book <- books.iterator()) {
...
<a href="@routes.Application.buy(book.id)" class="btn btn-primary"
}
Of course if your model's ID is other than String
you need to modify the route's param type
Update -- alternative using form/POST
A form with a POST method is a better solution, or the user will buy another book each time they click the URL, and the id will be exposed. Check out the forms documentation. Your template would be like this:
@for(book <- books.iterator()) {
...
<form method="post">
<div>@book.name</div>
<input type="hidden" value="@book.id"/><button type="submit">buy</button>
</form>
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With