AngularFaces: AngularJS Puts JSF on Steroids

Where Java Server Faces shines – and where it does not

Fork me on GitHubJSF 2.0 is a nice framework to create web applications. It offers a decent level of abstraction. Most of the time you don’t have to deal with basic technologies like HTML and Javascript. It fun to use it. You can create an attractive-looking application in no time.

But things become ugly once you start to write an AJAX client. It looks deceptively innocent at first sight. What’s so difficult about adding simple attributes like update="@form" or – if you happen not to use Primefaces – a nested tag like <f:ajax>? Beware: You’ll end up wading knee-deep in Javascript code, DOM trees and HTML. You’ll add an id to virtually every component of your dialogues, and you have to know a lot about when events are fired. Firebug soon becomes your best friend1.

The one thing I like about JSF is it simple, declarative approach. But once you start to write an AJAX client, simplicity soon gets lost. The more Javascript code you add, the more you move away from the declarative approach to a more imperative approach.

Javascript to the rescue?

During the last couple of months I’ve begun to prefer pure Javascript over AJAX. Not that I really liked the language. But I came to believe sometimes simple Javascript code is easier to maintain than all-too-clever JSF-AJAX code. Not to mention the network latency and costly server CPUs.

Later I learned about AngularJS. I was immediately struck by the similarity of the concepts. JSF facelets allow you to define an web application’s HTML in a declarative way. So does AngularJS.

Let’s combine ’em

So what about combining the two frameworks? Angular allows you to do most of the stuff you need AJAX for. The idea is to define a single-page app with JSF. The application communicates with the server by traditional JSF means: submit buttons. You may also use AJAX to make things smoother. But you can rid of most of your AJAX code, leaving it to AngularJS.

By doing so we get an AngularJS application without the need to create REST services. We can utilize the power and ease of JSF’s server side data binding, while still being able to unleash the power of client side Javascript.

That’s the idea behind the AngularFaces project: to create a JSF library allowing you to write an application without the need to use ids. AngularFaces is going to use the power of the client without sacrificing the simplicity of non-AJAX JSF.

Who the AngularFaces project is for

The project focuses on simplifying JSF. If you’re already an AngularJS programmer familiar with writing and using REST services, the project will probably be of little value to you. AngularFaces is going to offer a new way to communicate with the server, and it’s going to provide an easy entry to the Angular world to JEE programmers.

Two feasible approaches

Using Angular to make the JSF experience more pleasant is fine, but it’s only one of two or three possible approaches. It’s the approach I’m going to concentrate on in the first place. However, this is a somewhat limited approach. The idea of AngularJS is to manipulate the DOM tree freely. JSF is used to own the DOM tree. As you can imagine, this was a major challenge when I developed AngularFaces. Marco Rinck’s JUA library solves this problem. It allows you to combine AngularJS with JSF AJAX requests. However, the library doesn’t always work perfectly, and mastering AJAX adds another level of complexity, so my general recommendation is to avoid AJAX.

Following this approach, you end up with a collection of small single page applications working together. That’s not as radical as the pure single-page application approach of AngularJS. Instead, it helps you to cut a huge single-page application into a couple of smaller, more manageable slices.

On the long run, you might want to follow a more client-centric approach. Most likely, you’ll start writing pure AngularJS applications using REST approaches. In this case, AngularFaces is a merly step on the migration path, helping you to migrate from JSF to AngularJS.

There’s an alternative: by separating AngularJS code and JSF forms you can use JSF as an alternative communication means with the server. That’s what AngularFaces 2.x does. The disadvantage of REST services is their lack of state. Most people consider this an advantage, but sometimes you need state, and JSF’s powerful server communication comes in handy.

Marco Rinck came up with another interesting idea. He uses a traditional JSF application, but prefers AngularJS widgets over of server-side widgets. You can implement this approach with or without AngularFaces.

Current state of development

I soon found out it’s possible to combine AngularJS and JSF, even if it’s not without difficulties. You need JSF 2.2’s pass-through-attributes. However, the resulting code is verbose, even ugly. So I originally decided to hide the technical complexities in a JSF component library, based on the Primefaces library. That’s AngularFaces 1.0. It allowed you to write mix Angular and JSF code, brought some of the more importants JSR 303 annotations to the client and simplified the XHTML files even further by generating label and error messages without having to define them.

AngularFaces 2 brought a strategy shift. I found a way to turn AngularFaces into a plugin to MyFaces, Mojarra, BootsFaces and – with a couple of limitations – also PrimeFaces 5+. Now AngularFaces doesn’t have to implement widgets of its own (although there’s going to be an optional AngularFacesWidgets library). Key benefits of AngularFaces 2.1 are

  • simplified internationalization
  • a couple of rapid prototyping features
  • bringing the bean validation API (JSR303) to the client
  • an optional HTML-like syntax to write JSF views
  • and of course leveraging AngularJS in JSF applications.

A simple demo application (using the old AngularFaces 1.0 API)

I’d like to conclude with a little example. It allows you to enter two numbers and add them. Angular adds them as you type, and so does JSF after hitting the submit button.


(You can have a look at the live demo at the AngularFaces showcase).

The controller bean defines several constraints. Those constraints are evaluated on the client side as you type:

The AngularFaces components read the JSR 303 annotations and generate the Javascript and HTML code to check the constraints.

Just for the sake of demonstration I added some minor differences to the JSF error messages. After hitting the add button, JSF renders this page like so:

Of course, the final AngularFaces library is not intended to show any differences, no matter whether the page is displayed by JSF or AngularJS. Among other things, the Javascript code ought to be reponsible for coloring the label as you type. The image above shows an early prototype.

To generate the calculator page, you need this XHTML code:

<f:view <!-- boiler plate code ommitted --> >
  <h:head>
    <script src="calculatorController.js"></script>
  </h:head>
  <a:body ng-app="calculatorApp" ng-controller="calculatorController">
    <h:form ng:name="myform" id="myform">
      <h:panelGrid columns="2">
        <a:inputText label="First number" value="#{calculatorBean.number1}"/>
        <a:inputText label="Second number" value="#{calculatorBean.number2}" />
        <a:commandButton type="submit" value="add" action="#{calculatorBean.add}"/> 
        <h:outputText value="Angular Preview: 
                 {{toString(number1)}} + {{toString(number2)}} = {{add()}}" />
        <a:inputText label="JSF Result" value="#{calculatorBean.result}" />
      </h:panelGrid>
    </h:form>
    <h:messages />
  </a:body>
</f:view>

As you can see, this is a lot less code than you have to write using other JSF libraries. AngularFaces 2 even allows you to omit the label attribute. It uses the bean attribute name to guess the label (by “de-camel-casing” it).

The XHTML page automatically tries to load the controller, which is expected to have the same name as the ng-controller attribute (“calculatorController.js” in our case):

function calculatorController($scope) {
  $scope.add = function() {
    if ($scope.number1 && $scope.number2) {
      $scope.result = parseInt($scope.number1) + parseInt($scope.number2);
    } else
      $scope.result = "(undefined)";
    return $scope.result;
  };
  $scope.toString = function(number) {
    if (number)
       return number;
    else
       return "(empty)";
    }
}

That’s it for today. During the next couple of weeks I’m going to publish descriptions of various AngularFaces components. You can find the source code on GitHub at https://github.com/stephanrauh/AngularFaces. You can participate with the project by forking AngularFaces and sending me a pull request.

Feedback

I’d like to hear from you. Do you like or object the idea?


Dig deeper


  1. Experienced JSF programmers may consider my description a little exaggerated. That’s because you already know what to do – and what to do not. Watch a JSF newby to get my point.

12 thoughts on “AngularFaces: AngularJS Puts JSF on Steroids

  1. Pingback: AngularFaces: AngularJS Puts JSF on Steroids | ...

  2. Bernard

    You are crazy! I thought I’m too attached to JSF but now I see there are couple of steps ahead of me before loosing sanity completely.
    Best of luck with AngularFaces.

    IMHO one must choose but prove me wrong.

    Reply
    1. Stephan Rauh

      I take it as a compliment :).

      But sure you’re right. You’ll never be able to unleash the full power of AngularJS if you’re slowed down by JSF. The other way round – well, I’m not sure yet. That’s why I started AngularFaces. I do believe Angular’s able to smooth out some edges of JSF. My first experiments went surprisingly well. I’ve even been able to Angularize a PrimeFaces data table with in-cell-editing.

      By the way, doing something virtually impossible is a lot of fun!

      Reply
  3. Pingback: AngularJS Highlights: Week Ending 11 August 2013 | SyntaxSpectrum

  4. Yamada

    I disagree with the statement that when using ajax with JSF one will be handling a lot with javascript, DOM trees and HTML manipulation. About the ids it is true. If you dont want to refresh everything (using @all) one must take care of ids to specify exactly what you want to render/update after an ajax event/request.

    The only reason to use AngularJS in combination with JEE server side solution would be to completely decouple the UI team skills from the server side dev team. For example, if you want to hire a third party company to produce your web front end. And if you go to this approach it should be better to use JAX-RS on the server side.

    Reply
    1. Stephan Rauh Post author

      Oops, did I really mention DOM manipulation? If so, you’re right – it’s not a good idea to manipulate the DOM tree in a JSF program. Thank you for pointing this out! But it helps a lot to know a lot about HTML, CSS and Javascript. In theory, you can do without Javascript. In reality I saw my team using more and more Javascript.

      Basically my idea is to use AngularJS to smooth out some rough edges of JSF. This is particularly interesting if you’ve already got a JSF application. As for green field applications, I agree with you. When you’re free to choose the architecture, you’ll probably prefer pure AngularJS plus WebServices or REST.

      Reply
  5. Cliff Lo

    Hi Stephen,

    Here I would like to suggest if it is possible to add library of Dart import to your <a> tag? I would say it would be very helpful because this allows us to use AngularDart which would have compile time debugging instead of AngularJS.

    Regards,

    Cliff

    Reply
  6. jopss

    This can not be true! You’re breaking the Angular architecture for your lack of skill with Ajax? Is not it better to study?

    Reply
    1. Stephan Rauh Post author

      They say you know you’re on the right track when you start to attract hate. Obviously AngularFaces does something right :).

      I’m convinced AJAX can be done a lot better than standard JSF does. It leaves the hard work to the programmer, and that’s not the way it should be. I wrote BabbageFaces to fix this. The other option is AngularFaces, which allows you to split a huge AngularJS application into a collection of medium-sized, JSF-powered single page applications. If that’s breaking Angular’s architecture, so be it. Personally, I consider it a modernization of JSF, including nice features like using client-side widgets instead of rendering tons and tons of HTML code on the server. For instance, using ngtable instead of h:table makes your data-centric application a lot more responsive.

      Without AngularFaces, developers can’t adopt AngularJS without rewriting the entire JSF application. In companies running big programs consisting of hundreds of pages such a re-write usually isn’t possible. There are applications consisting of more than a million lines of code. You don’t re-implement such a thing on a week-end. AngularFaces helps developers to adopt AngularJS gradually. On the long run, they may gradually start to drop JSF if they see AngularJS serves them well.

      By the way, has anyone written an AngularJS application consisting of – say – 500 HTML pages? I’m curious whether the idea of a SPA still works with such a big application.

      Reply
  7. Nithin Meshram

    Hi Stephan,

    It is a good approach the way I see it – trying to bring in the best of both the worlds. I was looking for a way to use Spring with JSF and some good JS framework/library that would leverage the power available at modern day clients while still keeping the state and security at server side. I did not want to ditch JSF because first it’s a specification in the JEE and not likely to go away (distractors of JSF forget that developers in particular and companies in general have not been able to completely avoid JSP even today since it has been so much inherent part of the JEE). I see no reason why JSF wouldn’t enjoy the same status, say a 10 years from now.

    Having said that, you are right and I have experienced this in my JSF 2.0 code as well. A lot of String copy pasting happens (IDs and Bean Names and ELs) in a plain JSF page. Whether, you use Ajax4JSF or RichFaces or any component library, eventually the custom JavaScript that I have to write for my pages still is lot of boilerplate and also is hard to maintain – given that the developers often change teams/companies.

    Your approach seems promising and I am going to try out AngularFaces or just JSF and your mechanism of using Angular with it. The question is am not sure about the future of AngularFaces and what amount of user base / community audience will be available in future or will the mechanism be able to hold on to the upcoming changes in JSF and AngularJS since both are very actively developed and followed.

    Where and how do you see AngularFaces say a 5 years from now?
    Thank you
    Nithin

    Reply
    1. Stephan Rauh Post author

      I believe in five years AngularFaces will live in similar niche as OmniFaces does today: it will be a well-known and highly-respected framework many developers use, but probably it won’t be the number one on the JSF market.

      This bold claim is backed by the strategy shift I did in AngularFaces 2.0. AngularFaces doesn’t have to provide widgets of its own. It’s a simple plugin that integrates nicely with Mojarra, MyFaces, PrimeFaces and BootsFaces. So AngularFaces is much less ambitious than it used to be. Currently, the changes in AngularJS (most notably the new “controller as” syntax and AngularJS 2.0) are much more challenging than the JSF side.

      Apart from that, it depends on you, the community. The download numbers are rising. Last month I saw roughly 300 downloads from Maven Central. That’s enough to convince me to continue. There’s also a lot of traffic on my GitHub repository.

      As for what AngularFaces looks like in five years – well, there’s no five years plan. I’m one of the BootsFaces committers, so I can promise a good BootsFaces integration. The next goals are a better integration with PrimeFaces, and much, much better documentation. After that, I’d like to add a few client side widgets that integrate seamlessly into a BootsFaces application. For example, we could provide a client side tab view component, client side datatables and so on. The general idea is to move the components consisting of lots and lot of HTML code to the client, thus reducing network and server load significantly.

      By the way, it would help a lot if someone joined the project :). In particular, I could use a helping hand with documentation, testing and writing demo applications. Recently, a Brazilian developer offered to translate the documentation to Portuguese language. Things like this help a lot to keep the project alive!

      So

      Reply

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>