Search code examples
grailsgsp

Grails: Invoking Domain method from gsp


I have the following domain class:

package com.example

class Location {
   String state

    def getStatesList(){

    def states = ['AL','AK','AZ','AR','CA','CO','CT',
         'DC','DE','FL','GA','HI','ID','IL','IN','IA',
         'KS','KY','LA','ME','MD','MA','MI','MN','MS',
         'MO','MT','NE','NV','NH','NJ','NM','NY','NC',
         'ND','OH','OK','OR','PA','RI','SC','SD','TN',
         'TX','UT','VT','VA','WA','WV','WI','WY']
    return states
   }
} 

In my gsp, I am trying to display the state list in a select dropdown as such

<g:select name="location.state" class="form-control" from="${com.example.Location?.getStatesList()}" value="${itemInstance?.location?.state}" noSelection="['': '']" />

In doing so, I am receiving "missing method exception"

If I change the method with list, I no longer receive the error, but I don't want that.

from="${com.example.Location?.list()}"    // works
from="${com.example.Location?.getStatesList()}"     // does not work

Any help is greatly appreciated.


Solution

  • As dmahaptro said, you can correct this issue by making getStatesList() a static method.

    class Location {
       String state
    
       static List<String> getStatesList() {
             ['AL','AK','AZ','AR','CA','CO','CT',
             'DC','DE','FL','GA','HI','ID','IL','IN','IA',
             'KS','KY','LA','ME','MD','MA','MI','MN','MS',
             'MO','MT','NE','NV','NH','NJ','NM','NY','NC',
             'ND','OH','OK','OR','PA','RI','SC','SD','TN',
             'TX','UT','VT','VA','WA','WV','WI','WY']
       }
    } 
    

    Then you'll be able to execute Location.statesList or Location.getStatesList().

    Alternative

    I think a cleaner alternative is using a final constant:

    class Location {
       String state
    
       static final List<String> STATES =
             ['AL','AK','AZ','AR','CA','CO','CT',
             'DC','DE','FL','GA','HI','ID','IL','IN','IA',
             'KS','KY','LA','ME','MD','MA','MI','MN','MS',
             'MO','MT','NE','NV','NH','NJ','NM','NY','NC',
             'ND','OH','OK','OR','PA','RI','SC','SD','TN',
             'TX','UT','VT','VA','WA','WV','WI','WY']
    } 
    

    Then you can access the list the same way: Location.STATES. The difference is that the all-caps name implies a value that does not change (and does not require accessing the database).