September 6, 2008
In the process of building a Monte Carlo simulation engine, I stumbled across Eastwood, and the Google Chart API.
Diving in, I’ve discovered that the Google Chart API is pretty solid for simple charts - easy to get started, and fairly simple to experiment with by manipulating the URL.
And, if you’re using Grails, Eastwood is a plugin that converts JFreeChart to use the Google Charts API. Very nice.
July 29, 2008
One frustrating thing I’ve discovered with Grails is the way data is sent to the view pages.
In Rails, it looks a little like this:
@scenario = Secenario.new
@scenario.title = "New Scenario"
@scenario.description = "Add A Description Here"
render :view => 'create'
This snippet creates a new Scenario object, populates it, and tells Rails to render the create.rhtml file, with the @scenario object in the page’s model, helpfully known as @scenario
In Grails, it looks like this:
def scenario = new Scenario()
scenario.title = "New Scenario"
scenario.description = "Add A Description Here"
render( view: create, model: [ scenario: scenario ])
and, similarly, Grails knows to render the create.gsp file, and the scenario object is available to the page as scenario
Which isn’t terribly different, and fairly easy to use.
The problem comes in because of the way Grails uses closures to provide the action methods on the controllers (edit, create, delete, save, etc).
In Grails, you might have a action method as such:
def create = { // closure of action method here }
Now, look at the previous Grails code. Do you see the issue? Yes - create is now overloaded, and in some cases, Grails will attempt to find a page named Controller_closure_blah_blah_blah.jsp, which is obviously completely wrong.
The fix is simple:
render( view: 'create', model: [ scenario: scenario ])
Basically, make sure you always use quotes for your string values, even though the Groovy language allows you to leave the quotes off. Otherwise, you’ll occasionally get frustrating and confusing results.
July 24, 2008
Interesting issue that left me scratching my head this morning…
using gsp tags, you can iterate over arrays:
<g:each in="${myarray}">
<p>${it.title}</p>
</g:each>
but if you do something slightly more clever:
<g:each in="${myarray}">
<p><g:link action='myaction' id='${it.id}'>${it.title}</g:link></p>
</g:each>
You’ll get null pointer exceptions.
Why?
Because the <g:link> tag creates its own instance of the special variable it inside its own ‘domain’.
Fix
add the parameter var=’myvar’ to the <g:each”> tag: <g:each in=”${myarray}” var=”myvar”>. Then, use ${myvar.id} and ${myvar.title} in your code:
<g:each in="${myarray}" var="myvar">
<p><g:link action='myaction' id='${myvar.id}'>${myvar.title}</g:link></p>
</g:each>
And everything should work again.
July 23, 2008
If you’ve used Rails, you’re familiar with the flash, and all the nifty things you can do with it.
In Grails, you have flash, but you also have an entire tag library of <g:hasError>, <g:renderErrors> and so forth. None of which, as far as I can tell, care one whit about the flash. They’re all focused on domain objects, and the errors associated with processing them.
(In my opinion, this is one of the frustrations of Grails examples - the tendency to get the domain connected to the view via scaffolding, and then the author changes the subject)
But you can use the flash, in much the same way as Rails. For example, I put the following in my top-level layout template:
<g:if test="${flash.error}">
<div class="errorbox">
${flash.error}
</div>
</g:if>
<g:if test="${flash.message}">
<div class="messagebox">
${flash.message}
</div>
</g:if>
(note that you’ll have to define the messagebox and errorbox css classes)
Putting information into the flash is straightforward:
flash.error = "Your error message here."
Hope this helps!
March 17, 2008
Having taken up the task of learning Groovy, I stumbled early, as I tried to figure out how to integrate groovy-based unit tests with my java code. I had a java class called ContactScreen, and I wrote a groovy test case:
class ContactScreenTest extends GroovyTestCase {
void testStandardEmailScreen() {
screen = ContactHelper.getStandardContactScreen( Contact.EMAIL )
assertTrue( screen instanceof AnyDayEmailScreen )
}
}
Which failed when I tried to run it via Eclipse, giving the following error:
testStandardEmailScreen(ContactScreenTest)groovy.lang.MissingPropertyException: No such property: screen for class: ContactScreenTest
I stared at that error for a long time, wondering what the heck it meant. I mean, I’ve seen all sorts of example groovy scripts that don’t require definitions. In fact, the code I was modeling mine after used this very format. What is going on?
Finally, I turned to the groovy user group to help debug my groovy test case. Here’s what I found:
- The code I was looking at, circa 2004, is now victim to a fairly significant shift in language specification. In other words, it won’t compile anymore.
- The rules for declaring variables is different for scripts versus classes. In other words, if you are just running a script, you don’t need to declare variables. If you are building a class, you have to declare the members of the class via def.
So the working code looks like this:
class ContactScreenTest extends GroovyTestCase {
void testStandardEmailScreen() {
def screen = ContactHelper.getStandardContactScreen( Contact.EMAIL )
assertTrue( screen instanceof AnyDayEmailScreen )
}
}