Sunday, 1 December 2013

AngularPrime Enterprise: A proof of concept

Introduction

As explained in the StatelessPrime announcement, I was trying to create a front end with HTML5, CSS and JavaScript which was as easy as creating one with JSF (for me it is easy, I know a lot of people don’t find that easy).
And with the progress I made with the AngularPrime widgets, the look and feel of a PrimeFaces and AngularPrime application are almost identical.  But there are a few easy things in PrimeFaces /JSF that are still missing in the JavaScript based application.
And that was the goal of my AngularPrime Enterprise experiment, allow the creation of an application with the same ease and power as with PrimeFaces.

Why the name Enterprise

For me, JSF is at his best when you use it for administrative applications.  With his lifecycle containing converters, validators and action events, it is ideal for data input type of application that need some business logic checks before the data can be stored in a database.
Making this type of applications, which I refer to as Enterprise type, easier with AngularJS and AngularPrime, lead me to the, not so creative, name of AngularPrime Enterprise.

Messages

One thing which is very easy is the display of messages that you specify within the code.

FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("..."));

By decoupling the ability to set messages from the framework you display them, you can specify in a generic fashion some messages for the screen using CDI as explained in GenericMessage for DeltaSpike supporting JSF and REST
The messages are now available in a thread local variable and ready to be sent to the browser together with the response.  The ContainerResponseFilter I explained in the blog Even easier JAX-RS for Java EE 7 can be used for this purpose.

With AngularPrime Enterprise, the response from the REST response it automatically wrapped within a Transfer structure like this:

    @JsonSerialize(using = JsonPayloadSerializer.class)
    private JsonPayload data = new JsonPayload();
    private List<Message> messages = new ArrayList<>();

This structure can be extended to include also some security info or session info. (like name of logged in user).  Within AngularJS, this enriched response object can be used to automatically display the messages.  The current implementation looks something like this:

$httpProvider.responseInterceptors.push(function ($q, puiMessages, puiGrowl) {
        return function (promise) {
            var resolve = function (value) {

                if (('boolean' === typeof value.data.data )) {
                    puiMessages.clear();
                }

                if (value.data.messages && value.data.messages.length > 0) {
                    puiMessages.show(value.data.messages.filter(function (msg) {
                        return 'INFO' !== msg.severity;
                    }));
                }

                // Interceptor is also called for loading partials.  Then value.data is a String.  When loading from backed, it is always an object
                if (angular.isObject(value.data)) {
                    value.data = value.data.data;

                }

            };

            var reject = function (reason) {
                console.log("rejected because: ", reason);
            };

            // attach our actions
            promise.then(resolve, reject);

            // return the original promise
            return promise;
        }
    });


The puiMessages services is a prototype that I created based on the messages component of PrimeFaces to display the messages set by the backend. The interceptor also takes out the values in the data attribute of the Transfer object. 

So the transfer of additional information, like the messages, is done transparently and without the need of any code written by the developer.

Validation

Validation is also a key feature of AngularJS.  There are directives like ng-required and also custom validation rules can be created and used. So the implementation of an automatic validation process which shows the error messages, isn’t a difficult task.

puiClientValidation is a service in AngularPrime Enterprise which has a function validateForm, which takes a reference to a form element.

It checks with AngularJS the errors in this form and shows the error message in the same message widget we used to display the messages we saw in previous section.

For the input fields that have an error, it try to finds the label for this element (<label for=”” >) to show a ‘personalised’ error message like:

First name is required.

And the last thing the service method does, at this moment, is touching the field model values so that the field can be shown in red for example to indicate the place of the error.

Conclusion

With this first test, I came pretty close to some features which are available in PrimeFaces and JSF.  I was able to define some message in the CDI bean and show it on the screen. Without any intervention of the developer (no code required).

Also the client side validation possibilities of PrimeFaces can be recreated with AngularJS by using a custom validation service.  It should even be easier when I override the ngClick directive of AngularJS and define the call there so that there is even no need in your JavaScript code to do the call.

This how it can look like

angularPrimeEnterprise

The code can be found on GitHub and is tested on Glassfish 4 and WildFly 8 beta 1.