0
votes

I am new to grails and groovy. I am trying to find out how to render a response from an action in a grails controller IN THE SAME gsp - but in a DIFFERENT SECTION OF THE gsp - as the gsp that takes the request (in this case a web form gsp page)?

any links or turorials or just straight to the point "do this" kind of replies are welcomed.

========= background with my code attempt) =========

Here is the code I am working with. It is a Grails application in which I am using a bootstrap template (available for free on the internet of course).

Now the actual code itself for functionality works. What I am having an issue with is this:

I have a gsp page that uses a css template and another gsp temlate for layout (this is from the bootstrap theme). I can start the page with the gsp+css tempate using this code (snippet) in my gsp page:

<g:layoutBody/>

This allows me to call my calling controller code in this gsp file for the request:

<body>
<g:form name="form" controller="apiStart" id="form">
    <div><g:select name="protocolType" value="restCall" from="${["-select-", "GET", "POST", "PUT", "DELETE"]}"/> &nbsp <label>URL: </label><g:textField name="url" value="${url}" />
    &nbsp <label>username: </label><g:textField name="userName" value="${userName}" />  &nbsp <label>password: </label><g:textField name="passWord" value="${passWord}" /></div>

    %{--<div class="text-field"><label>URL: </label><g:textField name="url" value="${url}" /></div>--}%
    %{--<div class="text-field"><label>username: </label><g:textField name="userName" value="${userName}" /></div>
    <div class="text-field"><label>password: </label><g:textField name="passWord" value="${passWord}" /></div>--}%
    <br>
    <div><label>Use Advanced Parameters?</label><g:checkBox name="useAdvParms" value="${false}" /></div>
    <div class="text-field"><label>Header1: </label><g:textField name="header1" value="${header1}" /> &nbsp <label>Value1: </label><g:textField name="value1" value="${header2}" /></div>
    %{--<div class="text-field"><label>Value1: </label><g:textField name="value1" value="${header2}" /></div>--}%
    <div class="text-field"><label>Header2: </label><g:textField name="header2" value="${header3}" /> &nbsp <label>Value2: </label><g:textField name="value2" value="${header4}" /></div>
    %{--<div class="text-field"><label>Value2: </label><g:textField name="value2" value="${header4}" /></div>--}%
    <br>
    <div class="submit"><g:actionSubmit value="Submit" action="save"/></div>
</g:form>
</body>

And then this gsp code for the response:

<body>
<h3>API Test Results</h3>
API Tested: ${apiStart.url}, Response: ${apiStart.response3}
<br>
%{--<g:textArea name="myField" value="myValue" rows="20" cols="100"/>--}%
<div class="textarea"><label>Output</label><br><g:textArea name="myField" value="${apiStart.result3}"  />
</div>
%{--Responce Code: ${apiStart.response3}<br>--}%
%{--Response: <br> ${apiStart.result3} <br>--}%

</body>

My issueis this: it works fine as separate pages. I want to render the results of the request on the same page as the calling request.

in the screen shot attached: I want to put the results in the text box where it says "Output Displayed here...." screenshot of gsp page

I assumed templates in grails is the way to go about it; but I get a Java Null pointer exception when I try to insert the template into that part of the code.

here is the template gsp code:

<div>
    API Tested: ${apiStart.url}, Response: ${apiStart.response3}
    <br>
    %{--<g:textArea name="myField" value="myValue" rows="20" cols="100"/>--}%
    <div class="textarea"><label>Output</label><br><g:textArea name="myField" value="${apiStart.result3}"  />
    </div>
    %{--Responce Code: ${apiStart.response3}<br>--}%
    %{--Response: <br> ${apiStart.result3} <br>--}%
</div>

======== UPDATE: Addidng controller code =========== controller:

package hellograils

import org.springframework.http.HttpMethod
import org.springframework.web.client.RestTemplate

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;

import org.springframework.stereotype.Component;
import java.util.Base64;
import java.util.Map;

import static javax.xml.bind.DatatypeConverter.parseString;

class ApiStartController {

    def index() {

    }

    def save() {
        def apiStart = new ApiStart(params)
        apiStart.save()
        render (view: "apiStart", model: [apiStart: apiStart])

        System.out.println(apiStart.url);
        System.out.println(apiStart.passWord);
        System.out.println(apiStart.userName);

        RestTemplate restTemplate = new RestTemplate();

        System.out.println ("URI under Test is: " + String.valueOf(apiStart.url) + ". \n" + "Please stand by for results ... \n \n ");

        //String linkUT = apiStart.url;


//        apiStart.result3 = restTemplate.exchange(apiStart.url, HttpMethod.GET, null, String.class).getBody();
//        apiStart.response3 = restTemplate.exchange(apiStart.url, HttpMethod.GET, null, String.class).getStatusCode();



        if (apiStart.protocolType == "GET") {

            apiStart.result3 = restTemplate.exchange(apiStart.url, HttpMethod.GET, null, String.class).getBody();
            apiStart.response3 = restTemplate.exchange(apiStart.url, HttpMethod.GET, null, String.class).getStatusCode();
            render(view: "apiStart", model:[apiStart: apiStart])

            System.out.println(apiStart.protocolType);
            System.out.println(apiStart.result3);
            System.out.println(apiStart.response3);

        }

        else if (apiStart.protocolType == "POST") {

            //apiStart.result3 = restTemplate.exchange(apiStart.url, HttpMethod.POST, request, String.class).getBody();
            apiStart.result3 = restTemplate.execute(apiStart.url, HttpMethod.POST, null, String.class).getBody();
            apiStart.response3 = restTemplate.exchange(apiStart.url, HttpMethod.POST, null, Map.class).getStatusCode();
//            apiStart.result3 = restTemplate.exchange(apiStart.url, HttpMethod.POST, null, String.class).getBody();
//            apiStart.response3 = restTemplate.exchange(apiStart.url, HttpMethod.POST, null, String.class).getStatusCode();
            render(view: "apiStart", model:[apiStart: apiStart])

            System.out.println(apiStart.protocolType);
            System.out.println(apiStart.result3);
            System.out.println(apiStart.response3);

        }

        else if (apiStart.protocolType == "PUT") {

            render(view: "apiStart", "coming soon ....")

            System.out.println(apiStart.protocolType);
            System.out.println(apiStart.result3);
            System.out.println(apiStart.response3);

        }

        else if (apiStart.protocolType == "DELETE") {

            render(view: "apiStart", "coming soon ....")

            System.out.println(apiStart.protocolType);
            System.out.println(apiStart.result3);
            System.out.println(apiStart.response3);

        }

    }
}

=================== end of controller code ==================

and here is the domain controller code:

================ domain model code ==========================

domain:

package hellograils

class ApiStart {

    String url
    String userName
    String passWord
    String result3
    String response3
    String header1
    String header2
    String value1
    String value2
    String protocolType

//    static constraints = {
//    }
}

======================= end of domain ================

Can someone advise and show me the best way to do this?

thanks.

ironmantis7x

1

1 Answers

2
votes

Include the results pane in your gsp, but wrap it with a g:if tag. Supply a flag variable that determines whether grails renders that portion of the output or not.

<g:if test="${apiStart != null}"> 
  <div class="textarea">
    <label>Output</label><br>
    <g:textArea name="myField" value="${apiStart.result3}"  />
  </div>
</g:if>

In the edit method, define apiStart as:

def apiStart = params.apiStart

When the edit view is initially rendered, the results pane should not appear.

In the save method, do whatever you're doing, define the apiStart map, populate it, and redirect to the edit method passing the apiStart as a parameter.

redirect(view:'edit', params:[apiStart:apiStart])

Or something like that. Haven't seen your controller code...