Grails Angular Scaffolding

Grails Angular Scaffolding

By James Kleeh, OCI Software Engineer

August 2016


INTRODUCTION

Creating a single-page application (SPA) has never been easier with the new Grails Angular Scaffolding Plugin! This article provides a short tutorial on how to use the plugin.

The easiest way to get started with scaffolding is to use the Angular profile in Grails 3.2.0 or higher, which installs and configures the plugin automatically. See the documentation for information on how to get the plugin installed into an existing application.


GRAILS QUICKCAST: ANGULAR SCAFFOLDING

OCI Engineer, James Kleeh, walks you through using the Angular Scaffolding for Grails to build a fully functional web app, using a simple blog format for demonstration. The tutorial explains how to have Grails set up a REST endpoint and all the Angular modules needed to get the web app running. 

WATCH QUICKCAST


For this tutorial, we will be working with the following domain classes.

  1. package com.myblog
  2.  
  3. import grails.rest.Resource
  4.  
  5. @Resource(uri="/post")
  6. class Post {
  7. URL url
  8. PostContent postContent
  9. static embedded = ['postContent']
  10. static hasMany = [comments: Comment , tags: Tag]
  11. static constraints = {
  12. }
  13. }
  14. //---------------------------------
  15. package com.myblog
  16.  
  17. class PostContent {
  18. String title
  19. String body
  20. Date published
  21. static constraints = {
  22. }
  23. }
  24. //---------------------------------
  25. package com.myblog
  26.  
  27. import grails.rest.Resource
  28.  
  29. @Resource(uri="/tag")
  30. class Tag {
  31. String name
  32. static constraints = {
  33. }
  34. }
  35. //---------------------------------
  36. package com.myblog
  37.  
  38. import grails.rest.Resource
  39.  
  40. @Resource(uri="/comment")
  41. class Comment {
  42. String text
  43. static belongsTo = [post: Post]
  44. static constraints = {
  45. }
  46. }

Generating Assets

Generating client-side assets with this plugin is very easy. In this example, the domain class you would like to have assets generated for is com.myblog.Post:

grails ngGenerateAll com.myblog.Post 

To specify, you wish any generated files to overwrite existing files:

grails ngGenerateAll com.myblog.Post true 

You can also execute the same command with Gradle:

./gradlew ngGenerateAll -Pargs="com.myblog.Post true" 

Some assets that are generated are common to all scaffolded modules. The scaffolding will generate those assets in the “core” module. The core module will be created in the same package as the module being generated if it doesn’t already exist. If a core module already exists, it will not be overwritten, even if the overwrite parameter is true.

The following structure will be produced:

Note that other modules were created along with the post module.

The modules for the Tag and Comment domains do not provide CRUD functionality. They exist solely to assist the Post module.

In the future, if you wish to scaffold the CRUD of Tags or Comments, execute the ngGenerateAll command with the second parameter set to “true” so the existing assets will be overwritten.

Using the Assets

If you are using the Angular profile in Grails 3.2.0 or higher, none of the steps below are required because they are all done for you!

If you are working with an existing application, there are a few steps you must take to make everything work together as designed.

  1. Ensure that the required third-party libraries exist where the scaffolding expects them to be.

    The scaffolding requires angular, angular-resource, and ui-router to function as designed. The default locations for those assets are:

    • /angular/angular.js
    • /angular/angular-ui-router.js
    • /angular/angular-resource.js

    You can change the default locations with configuration. See the asset paths section in the documentation to learn how to do so.

  2. Ensure the required asset pipeline plugins have been imported.

    The scaffolding is designed around the use of three asset pipeline plugins. Include the plugins in your project via the instructions in the links below.

    Angular Annotate Asset Pipeline

    Angular Template Asset Pipeline

    JS Closure Wrap Asset Pipeline

  3. Ensure databinding handles the default date format.

    The scaffolding relies on the default format Angular applies to dates when they are included in a request. In Grails 3.1.x, the date format is not included in the default list of date formats that databinding will attempt to use. You can easily add it yourself via configuration.

     grails: 
    databinding:
    dateFormats:
    - "yyyy-MM-dd'T'HH:mm:ss.SSSX"
  4. Ensure the module is loaded on the page.

    If the “parent” module is already required by your current code, there is nothing you need to do to get the newly generated module to be included wherever the parent module is. The scaffolding will automatically attempt to create a module dependency and require statement in the parent module. Here is an example of what that might look like:

     grails ngGenerateAll com.myblog.Post 

    If grails-app/assets/javascripts/com/myblog/com.myblog.js exists, it will be considered the parent module. The scaffolding will attempt to edit the file to add a dependency to the post module.

    If a parent module does not exist, or the parent module isn’t being included on the desired page, it is up to you to use asset pipeline to include it where it is needed.

  5. Ensure a ui-view directive is on the page for the state to load HTML into.

    See the ui-view documentation on how to do this.

  6. Ensure the ng-app directive is on the page. ng-app="com.myblog.post"

  7. Navigate to the route http://localhost:8080/#post

CRUD

The following images depict what you will see when you have successfully navigated to the ‘post’ route and begin creating Posts.

List

Create

Note that clicking “Add Comment” at this time will not have any effect because the comment scaffolding has not been created.

Show

Generating Associated Domains

The logical next step is to generate the Tag scaffolding so we can create tags. This allows us to choose tags when creating or editing our Post.

grails ngGenerateAll com.myblog.Tag true 

Note that the second parameter “true” is important because we already had a Tag module that we will need to overwrite in order for the scaffolding to function correctly.

In addition, we can generate the comment scaffolding to assign comments to posts.

grails ngGenerateAll com.myblog.Comment true 

The following are screen captures of what you can expect once the associated domain classes are generated:

Tag

Create

Show

List

Comment

Create

Show

List

Conclusion

Now that all domain classes have scaffolding, you can manage your data in a SPA. The scaffolding is designed as a starting point for rapid development. Explore the generated JavaScript code and make changes to meet your business requirements. If you run into any issues, please submit an issue on the github page, or come chat with us about it in the Grails slack channel.

For a complete run through of installing and using the scaffolding in Grails 3.1.x, check out this quickcast!

The example project created in the video is available here.



Software Engineering Tech Trends (SETT) is a regular publication featuring emerging trends in software engineering.