GrailsInAction / graina2

Source code for the 2nd edition of Grails in Action
90 stars 92 forks source link

404 Error while User Registration (MEAP v13, ch7) #66

Open tikeswar opened 10 years ago

tikeswar commented 10 years ago

After the end of Section 7.3 (Command objects), when I click the Register button, I get a 404 error (please see the attached images), even when I use the code exactly at (https://github.com/GrailsInAction/graina2/tree/master/ch07/hubbub). Please help!

404errorwhileuserregistration1

404errorwhileuserregistration

tikeswar commented 10 years ago

Noticed that the password repeat field was missing in the online register.gsp(https://github.com/GrailsInAction/graina2/blob/master/ch07/hubbub/grails-app/views/user/register.gsp), so I went ahead and added that in the gsp as follows.

        <dt>PasswordRepeat</dt>
        <dd>
            <g:passwordField name="passwordRepeat" value="${user?.passwordRepeat}"/>
            <g:hasErrors bean="${user}" field="passwordRepeat">
                <g:eachError bean="${user}" field="passwordRepeat" var="err">
                    <p style="color: red;"><g:message error="${err}"/></p>
                </g:eachError>
            </g:hasErrors>
        </dd>

Then I added some println in the UserController.groovy for debugging as follows, ...

def register2(UserRegistrationCommand urc) {
    println ("------------" + "Here 1")
    println ("urc.loginId: " + urc.loginId)
    println ("urc.password: " + urc.password)
    println ("urc.passwordRepeat: " + urc.passwordRepeat)
    println ("urc.fullName: " + urc.fullName)
    println ("urc.bio: " + urc.bio)
    println ("urc.email: " + urc.email)
    if (urc.hasErrors()) {
        println ("------------" + "Here 2a")
        urc.errors.allErrors.each {err ->
            println("[$err.field]: $err")
        }
        println ("------------" + "Here 2b")
        return [ user : urc ]
    } else {
        println ("------------" + "Here 2c")
        def user = new User(urc.properties)
        user.profile = new Profile(urc.properties)
        if (user.validate() && user.save()) {
            flash.message = "Welcome aboard, ${urc.fullName ?: urc.loginId}"
            redirect uri: '/'
        } else {
            // May not be a unique loginId
            return [ user : urc ]
        }
    }
}

Then when I run the app and click on the "Register" button (as described in the original post), I get the following output from the println above.

------------Here 1
urc.loginId: tikeswar
urc.password: secret9
urc.passwordRepeat: secret9
urc.fullName: null
urc.bio: null
urc.email: null
------------Here 2a
[email]: Field error in object 'grailstuts.UserRegistrationCommand' on field 'email': rejected value [null]; codes [grailstuts.UserRegistrationCommand.email.nullable.error.grailstuts.UserRegistrationCommand.email,grailstuts.UserRegistrationCommand.email.nullable.error.email,grailstuts.UserRegistrationCommand.email.nullable.error.java.lang.String,grailstuts.UserRegistrationCommand.email.nullable.error,userRegistrationCommand.email.nullable.error.grailstuts.UserRegistrationCommand.email,userRegistrationCommand.email.nullable.error.email,userRegistrationCommand.email.nullable.error.java.lang.String,userRegistrationCommand.email.nullable.error,grailstuts.UserRegistrationCommand.email.nullable.grailstuts.UserRegistrationCommand.email,grailstuts.UserRegistrationCommand.email.nullable.email,grailstuts.UserRegistrationCommand.email.nullable.java.lang.String,grailstuts.UserRegistrationCommand.email.nullable,userRegistrationCommand.email.nullable.grailstuts.UserRegistrationCommand.email,userRegistrationCommand.email.nullable.email,userRegistrationCommand.email.nullable.java.lang.String,userRegistrationCommand.email.nullable,nullable.grailstuts.UserRegistrationCommand.email,nullable.email,nullable.java.lang.String,nullable]; arguments [email,class grailstuts.UserRegistrationCommand]; default message [Property [{0}] of class [{1}] cannot be null]
[fullName]: Field error in object 'grailstuts.UserRegistrationCommand' on field 'fullName': rejected value [null]; codes [grailstuts.UserRegistrationCommand.fullName.nullable.error.grailstuts.UserRegistrationCommand.fullName,grailstuts.UserRegistrationCommand.fullName.nullable.error.fullName,grailstuts.UserRegistrationCommand.fullName.nullable.error.java.lang.String,grailstuts.UserRegistrationCommand.fullName.nullable.error,userRegistrationCommand.fullName.nullable.error.grailstuts.UserRegistrationCommand.fullName,userRegistrationCommand.fullName.nullable.error.fullName,userRegistrationCommand.fullName.nullable.error.java.lang.String,userRegistrationCommand.fullName.nullable.error,grailstuts.UserRegistrationCommand.fullName.nullable.grailstuts.UserRegistrationCommand.fullName,grailstuts.UserRegistrationCommand.fullName.nullable.fullName,grailstuts.UserRegistrationCommand.fullName.nullable.java.lang.String,grailstuts.UserRegistrationCommand.fullName.nullable,userRegistrationCommand.fullName.nullable.grailstuts.UserRegistrationCommand.fullName,userRegistrationCommand.fullName.nullable.fullName,userRegistrationCommand.fullName.nullable.java.lang.String,userRegistrationCommand.fullName.nullable,nullable.grailstuts.UserRegistrationCommand.fullName,nullable.fullName,nullable.java.lang.String,nullable]; arguments [fullName,class grailstuts.UserRegistrationCommand]; default message [Property [{0}] of class [{1}] cannot be null]
------------Here 2b

Questions:

  1. Why are the email and fullName fields null, even though I have specified those in the form (please see the image in the original post)?
  2. How come urc.hasErrors() evaluates to true even though all the fields in the form are specified correctly?

Thank you!

pledbrook commented 10 years ago

The register2 action should probably do

render view: "register", model: [ user: urc ]

rather than

return [user: urc]

In answer to your secondary questions:

  1. The names of the text fields in the view are profile.fullName and profile.email, whereas the fields in the command object are fullName and email. The view needs updating. I'm not sure whether we should have a separate register2.gsp or specify the steps needed to update the register.gsp view.
  2. The fullName and email constraints are imported from the Profile domain class. The properties in domain classes are implicitly required, i.e. nullable: false, so fullName and email are required in the command object too.

Thanks for the report. There are several issues here that we need to fix.