Grails Cookbook - A collection of tutorials and examples

Grails 3 Vue.js Hello World Examples

The release of Grails 3 coincide with the growing popularity of more modern Javascript frameworks. Gone are the days where we mostly write code in gsp and jQuery. Frameworks like AngularJS, React, Ember and others are gaining popularity. For beginners, I highly recommend Vue.js because it is very easy to learn like Grails. A developer with some experience will be able to grasps how to use it in minutes. But as always, the hard part is in getting started. How can our single page application interact with our Grails 3 back end? Below are some basic examples for beginners. Here are some Grails 3 Vue.js Hello World Examples.

Grails 3 and Vue.js Example - No back end integration

We may begin our exploration by just using Vue.js as plain as possible, without any integration first. Then we will make the examples more complicated later. This sample is based on the guide on Vue.js official website. First, create a Controller and an action inside it:

class TestController {
    def sample1() { 
    }
 }

So for it to be able to render the page, let's create the file <grails-app>views/test/sample1.gsp. Then we may copy the example from Vue.js website (vuejs.org). Below is the code of this gsp file:

<!doctype html>
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Grails 3 and Vue.js Hello World Example 1</title>
    <script src="https://unpkg.com/vue@2.3.3/dist/vue.min.js"></script>
  </head>
  <body>
    <div id="app">
      {{ message }}
    </div>
    <script>
      var app = new Vue({
        el: '#app',
          data: {
          message: 'Hello World!'
          }
      })
    </script>
  </body>
</html>

Notice that we included the Vue.js library through CDN. Since this library is so simple and light, there is no need for any other complex way of installing it.

This is the most basic example on the Vue.js website where data and DOM are linked. app.message gets the value of "Hello World" and hence the div will render this text. Hence the output on the browser will be:
Hello World! 

Grails 3 and Vue.js Example - With Simple AJAX call

In the first example above, no data was retreieved from the Grails application. All were on the client side. Now we show how to call a method from a controller and render the result. We modify the controller's code:
package test
import grails.converters.JSON
class TestController {
    def sample2() { 
    }
    def greet(String name) { 
        def data = [greetings:"Hello ${name}"]
        render data as JSON
    }
}
So this implements a simple service that echoes back the passed name. Here is our sample2.gsp:
<!doctype html>
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Grails 3 and Vue.js Hello World Example 2</title>
    <script src="https://unpkg.com/vue@2.3.3/dist/vue.min.js"></script>
    <script src="https://unpkg.com/axios@0.16.1/dist/axios.min.js"></script>
  </head>
  <body>
    <div id="app">
      {{ message }}
    </div>
    <script>
      var app = new Vue({
        el: '#app',
          data: {
          message: 'Hello World!'
          }
      })
      axios.get('/test/greet?name=Mike')
        .then(function (response) {
          app.message = response.data.greetings;
        })
        .catch(function (error) {
          console.log(error);
      });
    </script>
  </body>
</html>
So initially, message will have the value "Hello World!". But then we use the axios library to invoke the greetings action on the test controller. We pass the name "Mike", and get the response "Hello Mike". Then this value is assigned to app.message and the div is updated accordingly. Hence the output will be:
Hello Mike 
But notice that this code is ugly:
axios.get('/test/greet?name=Mike')
It could be uglier if we need to pass more parameters. Here is a way to refactor it in a more elegant way:
<!doctype html>
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Grails 3 and Vue.js Hello World Example 2</title>
    <script src="https://unpkg.com/vue@2.3.3/dist/vue.min.js"></script>
    <script src="https://unpkg.com/axios@0.16.1/dist/axios.min.js"></script>
  </head>
  <body>
    <div id="app">
      {{ message }}
    </div>
    <script>
      var app = new Vue({
        el: '#app',
          data: {
          message: 'Hello Vuex!'
          }
      })
      axios.get('/test/greet', {
          params:{
            name:'Michael Jordan'
          }
        })
        .then(function (response) {
          app.message = response.data.greetings;
        })
        .catch(function (error) {
          console.log(error);
      });
    </script>
  </body>
</html>
And this will render:
Hello Michael Jordan 

Grails 3 and Vue.js Example - AJAX Call with Parameter from Input Box Then Triggered by Button Click

The past two samples uses hard-coded values that we pass to the controller action. Now we use input box and we submit after click of a button. Let's modify the controller first:
package test
import grails.converters.JSON
class TestController {
    def sample3() { 
    }
    def greet(String name) { 
        def data = [greetings:"Hello ${name}"]
        render data as JSON
    }
}
And here is the sample3.gsp code:
<!doctype html>
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Grails 3 and Vue.js Hello World Example 3</title>
    <script src="https://unpkg.com/vue@2.3.3/dist/vue.min.js"></script>
    <script src="https://unpkg.com/axios@0.16.1/dist/axios.min.js"></script>
  </head>
  <body>
    <div id="app">
      <p>{{ message }}</p>
      <input v-model="name"/>
      <button v-on:click="greetPerson">Greet</button>
    </div>
    <script>
      var app = new Vue({
        el: '#app',
          data: {
            message: '',
            name: ''
          },
          methods: {
            greetPerson: function () {
                axios.get('/test/greet', {
                    params:{
                      name:this.name
                    }
                  })
                  .then(function (response) {
                    app.message = response.data.greetings;
                  })
                  .catch(function (error) {
                  console.log(error);
                });
            }
          }
      })
    </script>
  </body>
</html>
In this example we have an input box and a button. In the first two samples, we only show the data part of Vue.js. Now we add methods and how to invoke them. The button is binded to the greetPerson method when it is clicked. Inside the greetPerson method we placed the very simple axios method call that we introduced above. Hence if we put "Larry Bird" and click the greet button, we get the message:
Hello Larry Bird
The examples above shows how easy it is to get started with Vue.js and Grails 3. This is by no means aimed to show how to write production quality code. But it gives gentle introduction in modern Javascript frameworks.