Grails
  1. Grails
  2. GRAILS-5568

Errors null - command object - edit closure

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Blocker Blocker
    • Resolution: Won't Fix
    • Affects Version/s: 1.2-RC2
    • Fix Version/s: 1.2 final
    • Component/s: Controllers
    • Labels:
      None
    • Environment:
      Windows XP

      Description

      There are data inconsistencies in our historical database, so the users have asked us to display errors when edit.gsp is loaded. The page is backed by a command object declared at the bottom of the controller class file. The command object is annotated with @Validateable. Within the edit closure we have

      accountDetailsCommand.errors.rejectValue('username','username.format')

      This line generates an exception in Grails 1.2.0.RC2 - "Cannot invoke method rejectValue() on null object"

      In Grails 1.1.1 and 1.1.2 this error sometimes occurred on hot-reload, but it never happened once the application was running.

        Activity

        Hide
        Jeff Scott Brown added a comment -

        I haven't investigated the real cause of this yet but why are you marking a command object as @Validateable? Command objects are made validateable by default.

        Show
        Jeff Scott Brown added a comment - I haven't investigated the real cause of this yet but why are you marking a command object as @Validateable? Command objects are made validateable by default.
        Hide
        Martin Flower added a comment -

        Hi Jeff, so I have AccountController.groovy which contains AccountController and AccountDetailsCommand. When I first attempted to access the errors in the edit{} closure, errors was null. I raised the question on the mailing list and received the following reply

        http://old.nabble.com/Re%3A-Error-messages-within-edit%7B%7D-p26779988.html

        and when I used @Validateable it worked - as long I restarted grails each time I made a change.

        Hope that makes sense.

        Martin

        Show
        Martin Flower added a comment - Hi Jeff, so I have AccountController.groovy which contains AccountController and AccountDetailsCommand. When I first attempted to access the errors in the edit{} closure, errors was null. I raised the question on the mailing list and received the following reply http://old.nabble.com/Re%3A-Error-messages-within-edit%7B%7D-p26779988.html and when I used @Validateable it worked - as long I restarted grails each time I made a change. Hope that makes sense. Martin
        Hide
        Martin Flower added a comment -

        Maybe I should also say that I call new AccountDetailsCommand() within the edit{} closure. Is there a better way ?

        Show
        Martin Flower added a comment - Maybe I should also say that I call new AccountDetailsCommand() within the edit{} closure. Is there a better way ?
        Hide
        Jeff Scott Brown added a comment -

        You should not be creating an instance of the command object class yourself. If your controller action accepts a command object as an argument, one will be created, populated with request parameters and validated and then will be passed as an argument into your controller action.

        If you can create a simple app that is representative of what you are trying to do and attach that here, I can help you sort out the best solution.

        Show
        Jeff Scott Brown added a comment - You should not be creating an instance of the command object class yourself. If your controller action accepts a command object as an argument, one will be created, populated with request parameters and validated and then will be passed as an argument into your controller action. If you can create a simple app that is representative of what you are trying to do and attach that here, I can help you sort out the best solution.
        Hide
        Martin Flower added a comment -

        I haven't got the code in front of me, but I think the sequence of urls is

        account/show/1234
        account/edit/1234

        in the show{} closure I call Account.get(params.id) and then call a method

        accountDetailsCommand = populateCommandFromAccount(account) which calls new AccountDetailsCommand()

        and then return accountDetailsCommand to the view - no problem.

        in edit{} I'm basically trying to do the same thing, but add error messages as well. All works, apart from the error messages.

        Do I need to add all the properties of AccountDetailsCommand to the request so that it can be instantiated automatically in the edit{} closure ? that is

        account/edit?name=zxc&country=ytr&telephone=terte&....

        I'll look at the code again tomorrow and aim to come back with a Hello World application.

        Thanks

        Martin

        Show
        Martin Flower added a comment - I haven't got the code in front of me, but I think the sequence of urls is account/show/1234 account/edit/1234 in the show{} closure I call Account.get(params.id) and then call a method accountDetailsCommand = populateCommandFromAccount(account) which calls new AccountDetailsCommand() and then return accountDetailsCommand to the view - no problem. in edit{} I'm basically trying to do the same thing, but add error messages as well. All works, apart from the error messages. Do I need to add all the properties of AccountDetailsCommand to the request so that it can be instantiated automatically in the edit{} closure ? that is account/edit?name=zxc&country=ytr&telephone=terte&.... I'll look at the code again tomorrow and aim to come back with a Hello World application. Thanks Martin
        Hide
        Martin Flower added a comment -

        Looking again at the documentation, I see that command objects are designed to handle form submission. I have used them also for displaying data. In my database I have many different domain objects - I retrieve and enrich selected information from these to display on the screen, and to allow the user selected updates. I use a command object to display the information, and the same command object to retrieve information for update. So I use new() in my show{} closure (never a problem). Today I have stopped using new() in my edit{} closure, and I reference the command object in the closure parameters - this instantiates a command with just an id field, everything else null. I need to call command.clearErrors(), then populate the command details from the selected domain objects, I can then populate errors with any warnings that the users wish to see highlighted (which was the original requirement).

        In summary, this JIRA can be set to resolved. Is my usage of command object for data display unusual (new() command in show{}) ? Is there a better way ?

        Show
        Martin Flower added a comment - Looking again at the documentation, I see that command objects are designed to handle form submission. I have used them also for displaying data. In my database I have many different domain objects - I retrieve and enrich selected information from these to display on the screen, and to allow the user selected updates. I use a command object to display the information, and the same command object to retrieve information for update. So I use new() in my show{} closure (never a problem). Today I have stopped using new() in my edit{} closure, and I reference the command object in the closure parameters - this instantiates a command with just an id field, everything else null. I need to call command.clearErrors(), then populate the command details from the selected domain objects, I can then populate errors with any warnings that the users wish to see highlighted (which was the original requirement). In summary, this JIRA can be set to resolved. Is my usage of command object for data display unusual (new() command in show{}) ? Is there a better way ?
        Hide
        Martin Flower added a comment -

        ok, no clearErrors() in 1.1 ... but otherwise it works

        Show
        Martin Flower added a comment - ok, no clearErrors() in 1.1 ... but otherwise it works
        Hide
        Graeme Rocher added a comment -

        I'll let Jeff comment on alternative options

        Show
        Graeme Rocher added a comment - I'll let Jeff comment on alternative options
        Hide
        Jeff Scott Brown added a comment -

        Martin,

        As you noted, Grails' "command objects" (probably not the best name we could have used) are really designed to help support form submission. It sounds like you are using them for a different purpose. My recommendation is not to do that. If you have these classes that you want to populate in a controller for the purpose of sending those objects into the view for rendering and you want those objects to be validateable, define a class under src/groovy/com/mypackage/etc and mark it as @Validateable. If you want to accept form submission parameters and have them automatically bound to an object and validated, use command objects.

        I hope that makes sense.

        Show
        Jeff Scott Brown added a comment - Martin, As you noted, Grails' "command objects" (probably not the best name we could have used) are really designed to help support form submission. It sounds like you are using them for a different purpose. My recommendation is not to do that. If you have these classes that you want to populate in a controller for the purpose of sending those objects into the view for rendering and you want those objects to be validateable, define a class under src/groovy/com/mypackage/etc and mark it as @Validateable. If you want to accept form submission parameters and have them automatically bound to an object and validated, use command objects. I hope that makes sense.

          People

          • Assignee:
            Jeff Scott Brown
            Reporter:
            Martin Flower
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development