Reputation: 159
I am attempting to call a service I created in a controller. This is the service:
package matriculation
import grails.transaction.Transactional
import groovy.sql.Sql
@Transactional
class StudNamesService {
def getNameById(String id) {
return id
}
}
And this is part of the controller
package matriculation
import static org.springframework.http.HttpStatus.*
import grails.transaction.Transactional
@Transactional(readOnly = true)
class MatrEntryController {
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def studNamesService
def getNameById(String id){
return studNamesService.getNameById(id)
}
}
When ever I call the method inside of my controller that calls the service, I get the following error:
Class: java.lang.NullPointerException
Message: Request processing failed; nested exception is org.grails.gsp.GroovyPagesException: Error evaluating expression [cont.getNameById(matrEntryInstance.peopleCodeId)] on line [61]: Cannot invoke method getNameById() on null object
Caused by:Cannot invoke method getNameById() on null object
I have done minimal changes to the code for this question. As you can see, the call in the controller has the exact same name as the name of the service, as it should. I am running Grails 3.1.1
Edit 1 This is part of the GSP page that is calling the method:
<%@ page import="matriculation.MatrEntryController" %>
<%
def cont=grailsApplication.classLoader.loadClass("matriculation.MatrEntryController").newInstance()
%>
<!----------------------Skip a few lines----------------------------->
<table>
<thead>
<tr>
<th id="cols">Options</th>
<g:sortableColumn property="peopleCodeId" title="People Code ID" id="cols"/>
<g:sortableColumn property="cadetName" title="Cadet Name" id="cols"/>
<g:sortableColumn property="soff" title="SOFF" id="cols"/>
<g:sortableColumn property="infirmary" title="Infirmary" id="cols"/>
<g:sortableColumn property="hsRotc" title="HS ROTC" id="cols"/>
<g:sortableColumn property="idfy" title="IDFY" id="cols"/>
<g:sortableColumn property="pao" title="Public Affairs" id="cols"/>
<g:sortableColumn property="busOffice" title="Business Office" id="cols"/>
<g:sortableColumn property="telephone" title="Telephone" id="cols"/>
<g:sortableColumn property="computer" title="Computer" id="cols"/>
<g:sortableColumn property="athletics" title="Athletics" id="cols"/>
<g:sortableColumn property="financialAid" title="Financial Aid" id="cols"/>
<g:sortableColumn property="compass" title="Compass" id="cols"/>
<g:sortableColumn property="regFlag" title="Registration Flag" id="cols"/>
<g:sortableColumn property="busOfficeForm" title="${raw('Business<br/>Office Form')}" id="cols"/>
</tr>
</thead>
<tbody>
<g:each in="${matrEntryList}" status="i" var="matrEntryInstance">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
<td id="cols">
<g:form resource="${matrEntryInstance}" method="DELETE">
<a href="${createLink(controller:'matrEntry',action:'show')+'/'+matrEntryInstance.id}" class="btn btn-default">Show</a>
<a href="${createLink(controller:'matrEntry',action:'edit')+'/'+matrEntryInstance.id}" class="btn btn-default">Edit</a>
</g:form>
</td>
<td id="cols">${matrEntryInstance.peopleCodeId}</td>
<td id="cols">${cont.getNameById(matrEntryInstance.peopleCodeId)}</td>
<td id="cols">${matrEntryInstance.soff}</td>
<td id="cols">${matrEntryInstance.infirmary}</td>
<td id="cols">${matrEntryInstance.hsRotc}</td>
<td id="cols">${matrEntryInstance.idfy}</td>
<td id="cols">${matrEntryInstance.pao}</td>
<td id="cols">${matrEntryInstance.busOffice}</td>
<td id="cols">${matrEntryInstance.telephone}</td>
<td id="cols">${matrEntryInstance.computer}</td>
<td id="cols">${matrEntryInstance.athletics}</td>
<td id="cols">${matrEntryInstance.financialAid}</td>
<td id="cols">${matrEntryInstance.compass}</td>
<td id="cols"><g:formatDate date="${matrEntryInstance.regFlag}" format="dd MMM, yyyy"/></td>
<td id="cols">${matrEntryInstance.busOfficeForm}</td>
</tr>
</g:each>
</tbody>
</table>
Upvotes: 1
Views: 745
Reputation: 24776
The issue here is that you are approaching the problem in the wrong way. You should not be creating an instance of a controller in the GSP page. Since what you are looking to do is call a service you should really look at using a tag library instead.
Here is a simple example of a tag library and it's use from your GSP:
package com.example
class ExampleTagLib {
static namespace = "myLookup"
def exampleService
def lookupName = { attrs, body ->
if (!attrs.id) return
out << exampleService.getNameById(attrs.id)
}
}
Use in your GSP would look like this:
<td id="cols">${myLookup.lookupName(id: matrEntryInstance.peopleCodeId)}</td>
I highly recommend reading the documentation for creating tag libraries before you give this a try.
Upvotes: 2