How to use jQuery to send JSON data to a Grails app

This took me a while to figure out, so here it is for anyone else who’d like to know. Firstly, I was quite surprised to learn that jQuery doesn’t have a built in method for turning objects into JSON, so you’ll need the JSON parser/creator from json.org. Then you can write your javascript POST function using the jQuery ajax method. Here I’ve left the content type as text/plain, which is not strictly correct but works with the Groovy code.

function postTreeData(){
    $.ajax({
        type: "POST",
        url: "savedata",
        contentType : "text/plain",
        dataType: 'json',
        data: JSON ...
more ...

Hibernate magic with lazy evaluation

I’ve just run across this phenomenon for the first time and it turns out that hibernate can be even lazier than I thought! To illustrate lets use this time-honoured example in Grails.

Here are our domain objects:

class Book {  
    String title  
    static belongsTo = [author : Author]  
    static constraints = {  
    }  
}  
class Author {  
    String name  
    static hasMany = [books : Book]  
    static constraints = {  
    }  
}

and we’ll add some sample data in our bootstrap.groovy:

def init = { servletContext ->  
    def alice = new Author(name: 'alice').save()  
    def book1 = new Book(title: 'book1')  
    def book2 = new Book(title: 'book2')  
    alice.addToBooks(book1)  
    alice.addToBooks(book2)  
}

Now we’ll ...

more ...

Functional Abstraction examples from SCIP in Groovy

I've been checking out the legendary MIT Structure and Interpretation of Computer Programs course from 1986 on YouTube, and it's fascinating for many reasons, not least the hypnotic synthesized Bach that bookends each lecture. I don't think I will ever be able to hear Jesu, joy of man's desiring again without seeing that purple wizard. What's really striking to me is how quickly the course gets into territory that I (coming from a self-taught Perl/Java background) think of as pretty advanced. In the first three lectures we are introduced to:

  • Recursive subroutines
  • big-O notation ...
more ...

Extending Java number classes with random functions in Groovy

Recently I’ve been playing around quite a bit with Processing.org, and one of the things that I often want to do is add a bit of noise to variables that represent positions, sizes, colours, etc. Most of the Processing functions that actually draw something (like lines, ellipses, etc) take their arguments in the form of floats, but most floating number operations in Java/Groovy return BigDecimal data types so we have to use casts a lot. Also, there’s no concise way to get a floating random number in a certain range that can be either negative or ...

more ...

Beware of the default acegi Grails plugin setup

This is firmly in the “putting it up here just in case anyone else has the same problem” category. There is a gotcha that bites when writing a Grails application that uses the acegi security plugin along with a postgresql database as the data source. The problem is that the acegi plugin will, by default, create a domain class with the name User. When you try to run the application with a postgresql datasource, GORM will try to create a table with the name user, which postgresql will not like as it is a reserved word.

This is a particularly ...

more ...

A pitfall to avoid when using the Grails UIPerformance plugin

A quick warning to anyone who’s using the excellent UIPerformance plugin for grails: don’t do what I did, and set up your bundles with identical names:

uiperformance.bundles = [

    [type: 'css',
        name: 'bundled',
        files: ['reset',
            'style',
            'invalid',
            'jquery.jcarousel']],

    [type: 'js',
        name: 'bundled',
        files: [
            'jquery-1.3.2.min',
            'simpla.jquery.configuration',
            'facebox',
            'jquery.jcarousel.pack',
            'cert']]
]

Unsurprisingly, this causes the plugin to get confused; the following works much better:

uiperformance.bundles = [

    [type: 'css',
        name: 'bundled_css',
        files: ['reset',
            'style',
            'invalid',
            'jquery.jcarousel']],

    [type: 'js',
        name: 'bundled_javascript',
        files: [
            'jquery-1.3.2.min',
            'simpla.jquery.configuration',
            'facebox',
            'jquery.jcarousel.pack',
            'cert']]
]
more ...