Search code examples
grailsgsp

Unable to Populate select-option tag using g:select in Groovy


I am trying to run the sample Collab-Todo application as in book Beginning Groovy and Grails,page no.123 (Author:Christopher M. Judd,Joseph Faisal Nusairat,and James Shingler Publication:Apress and Edition:2008). Here is my User.groovy file:

package collab.todo

class User {

    String userName
    String firstName
    String lastName
    static hasMany = [todos: Todo, categories: Category]
    static constraints = {
        userName(blank:false,unique:true)
        firstName(blank:false)
        lastName(blank:false)
    }
    String toString () {
        "$lastName, $firstName"
    }
}

The UserController.groovy is as Follows:

package collab.todo

class UserController {

    def scaffold = User
    def login = {

    }
    def handleLogin = {
        def user = User.findByUserName(params.userName)
        if (!user) {
            flash.message = "User not found for userName: ${params.userName}"
            redirect(action:'login')
        }
        session.user = user
        redirect(controller:'todo')
    }
    def logout = {
        if(session.user) {
            session.user = null
            redirect(action:'login')
        }
    }
}

I am able to create,read,update or delete the User table as usual.Here is a sample screenshot of my User view: The User List In the scaffolding view, I am trying to show the list of all the users in a drop-down(as per the book) using following snippet inside the user/login.gsp:

<g:select name='userName' from="${User?.list()}"
               optionKey="userName" optionValue="userName"></g:select>

But what I am getting in the login page is a dropdown with no values populated: Here is the screenshot of the login page: The user/login.gsp view

In case I change

from="${User?.list()}"

to

from="${User.list()}"

I am getting a NullPointerException. So any clues what is going on?


Solution

  • It looks like the User class could not be found from your view.

    Try one of the following:

    Add the import statement to your view.

    <%@ page import="collab.todo.User" %>
    

    Or use the fully qualified name within from attribute.

    from="${collab.todo.User.list()}"
    

    The best practice would be to pass the list of users from the controller:

    def login = {
        [users: User.list()]
    }
    

    And use the collection within your view

    from="${users}"