Вопрос

I cannot render the errors from my command object. It does the job well but my .gsp view does not render the errors I raise.

Here is my controller action:

def handleModifyProfile2 = { CreditProviderModificationCommand cpmc -> // bind params to the command object
   if (cpmc.hasErrors()) {
      flash.message = "Error modifying your profile:"
      redirect(action: "modifyProfile", params: [creditProvider : cpmc])
   } ...

Here is how I try to render the errors in my .gsp view:

<g:hasErrors bean="${creditProvider}">
   <div class="errors">
       <g:renderErrors bean="${creditProvider}" as="list" />
   </div>
</g:hasErrors>

How can I get the errors to be displayed in the view?

Это было полезно?

Решение

You can't send the command across in a redirect using params. You have a couple options:

  • render() in the error condition instead of redirect()ing:

    if(cpmc.hasErrors()) {
        render(view: 'profile', model: [creditProvider: cpmc])
    }
    

    This is the most common idiom for what you're doing.

  • Store the command in the session to persist it across the redirect:

    if(cpmc.hasErrors()) {
        session.cpmc = cpmc
        redirect(...)
    }
    
    // and in your action
    def cpmc = session.cpmc ?: null
    render(view: 'profile', model: [creditProvider: cpmc])
    

    This option is somewhat questionable. If not done correctly, you can pollute the session and leave objects hanging around, taking up memory. If done correctly, though, it can be a decent way to implement a post-redirect-get.

Другие советы

With Grails 3 (I don't know if this worked earlier) it's possible to use the flash for this. According to the documentation, the flash will be "cleared at the end of the next request".

I like to use a pattern like this:

def save(MyDomain myDomain) {
    if (myDomain.validate()) {
        myDomain.save()
    } else {
        flash.errors = myDomain.errors
    }
    redirect(action: 'edit', id: myDomain.id)
}

def edit(MyDomain myDomain) {
    if (flash.errors) {
        myDomain.errors = (Errors) flash.errors
    }
    return [myDomain: myDomain]
}

I don't like to use render() for this kind of error handling, because it makes URLs shown in the browser inconsistent with the shown page. This breaks when users set bookmarks, for example.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top