Micor
Micor

Reputation: 1542

Binding from JSON to enum in Grails

Running Grails 2.4.2 I cannot get enum binded from JSON string. I thought declaring a constructor that takes in value would solve the problem but it did not. I also tried passing JSON with name: "GENERIC", which did not bind either.

It is possible to bind to Enum if the value submitted as STRING. But that mean changing how JSON for enums inputed for binding vs rendered by default. Example, this works:

{"id":null,"templateCode": "GENERIC"}

What is the right/best way of getting enum binded from JSON?

class EmailTemplate {
    TemplateCode templateCode
}


public enum TemplateCode {
    GENERIC('Generic template'),
    CUSTOM('Custom template')

    final String value

    EmailTemplateCode(String value) {
        this.value = value
    }

    String getKey() {
        name()
    }

    String toString() {
        value
    }
}

In Bootstrap.groovy

JSON.registerObjectMarshaller(Template) {
    def map = [:]
    map['templateCode'] = it.templateCode
    return map
}

JSON.registerObjectMarshaller(TemplateCode) {
    def map = [:]
    map['name'] = it.name
    map['value'] = it.value
    return map
}

JSON being sent is

{"id":null,"templateCode":{"key":"GENERIC","value":"Generic template"}}

Edit: Simplified version

If we will use enum at its basic, making :

public enum TemplateCode {
    GENERIC,CUSTOM
}

Grails will render it to JSON as:

templateCode:  { enumType: com.EmailTemplateCode, name: GENERIC}

However, posting the same JSON string, will give an error and not bind to enum. The only way to do it, as mentioned above is by sending templatecode as a String:

templateCode: GENERIC

Upvotes: 2

Views: 1103

Answers (1)

billjamesdev
billjamesdev

Reputation: 14640

Well, this will do what you want, but there's probably a better way to make ALL enums render in this fashion. In the bootstrap, use:

JSON.registerObjectMarshaller(TemplateCode) {
    return it.toString()
}

This will properly render the EmailTemplate like:

{"templateCode":"CUSTOM"}

Upvotes: 2

Related Questions