Search code examples
grailsdata-binding

binding a command object with ValueConverter


In my Grails 2.3.7 app, I have the following command object

class UpdateThresholdsCommand {
    Double threshold_1
    Double threshold_2
}

The parameters I'm trying to bind to these properties are formatted currency values, e.g. threshold_1=$2,459.04&threshold_2=$1,459.04

I've defined the following implementation of ValueConverter to perform this binding

class CurrencyStringToDoubleConverter implements ValueConverter {

    FormatService formatService

    @Override
    boolean canConvert(Object value) {
        value instanceof String
    }

    @Override
    Object convert(Object value) {
        formatService.parseCurrency((String) value)
    }

    @Override
    Class<?> getTargetType() {
        Double
    }
}

and registered it in resources.groovy

currencyStringToDoubleConverter(CurrencyStringToDoubleConverter) {
    formatService = ref('formatService')
}

But when a request with params such as those shown above is sent to the action, CurrencyStringToDoubleConverter is never invoked, so the threshold_1 and threshold_2 properties of the command object are null. Why isn't CurrencyStringToDoubleConverter being invoked?


Solution

  • The approach you describe does work. See the app at https://github.com/jeffbrown/donalconverter. Run that app and click the link on the main index page. The FormatService is hardcoded to return 21.12 (see https://github.com/jeffbrown/donalconverter/blob/7a01031deceeea0d857af23f58686b4f1f824e1d/grails-app/services/demo/FormatService.groovy#L7) but the app demonstrates that the converter is being invoked and that the converter is delegating to the service.

    You have not shown what your FormatService is doing. It may be that there is something wrong in that code and that is throwing an exception, in which case your command object should have a corresponding binding error associated with it.

    It is difficult to say what is going wrong without seeing your code or seeing any relevant errors, but the linked app should demonstrate that the converter is being invoked, at least in that app.

    The relevant files in the app:

    I hope that helps.