; last updated - 13 minutes read

Fork me on GitHubIt was a hot summer day when I was sitting in the garden and started to dream. Wouldn't it be nice to add AngularJS to JSF?

Today it's a sunny day too, I'm sitting in the garden again and AngularFaces 2.0 is finished (it's even available on Maven Central). Now it's possible to use AngularJS without abandoning JSF. Even better: it's very simple, and AngularFaces 2.0 has much more in store for you. It adds a couple of features beyond AngularJS, such as bringing the Bean Validation annotations to the client and helping you to target an international market by reducing the boiler plate code needed to translate an application. AngularFaces is worth a look if you don't want to involve yourself AngularJS programming.

A little bit of history

Before reporting about the technical stuff I'd like to tell you how AngularFaces came into being. In its short history (less than 14 months) AngularFaces went twisted, almost convoluted paths before finally arriving at the goal. Today it is a very small framework (27 Java classes and two Javascript files). It wasn't always so: AngularFaces 1.0, which was a lot less powerful, needed 50 classes.

The original idea of AngularFaces was just that: adding AngularJS to JSF. At the time I was pretty familiar with writing JSF components, so defining a set a Angular-aware JSF components was a natural choice. Of course I wanted to provide feature-rich components without inventing the wheel from scratch, so I decided to derive my components form existing components. As it turned out, the widgets of PrimeFaces are up to the task. It's easy to derive your own component from a PrimeFaces component, and they are very versatile indeed. Plus, I like the elegant programming style of the PrimeFaces source code. I can read their source codes easily. Needless to say this makes adding functionality a lot easier.

In just a few weeks I found out how to integrate AngularJS in a JSF page and started to produce the first dozen components. Even this early time people started to notice. Papapetrou Patroklos scooped several of my articles. As far as I remember, AngularFaces was even mentioned at AngularJS Daily. Mind you, AngularFaces wasn't much more than vaporware at the time.

Everything was fine until I started to think about the data table. I achieved a certain level of integration, but it wasn't a deep integration. <prime:dataTable> is a fine piece of art, containing dozens of features and providing almost everything you'll ever want. It wasn't easy to derive a component from it without copying the entire code.

The weakness of my approach was that I tried to derive from components that have been designed without being extended in mind. The only way to modify the behavior of a parent class is to redefine its methods. As it turned out, PrimeFaces methods do to much (at least from my perspective). You can easily derive a class from a PrimeFaces class, but then you end up copying a lot of code. In other words: your components don't benefit form the advancements of future PrimeFaces components. That wasn't my goal at all. I didn't want to copy PrimeFaces, I wanted to write a minimal-invasive plugin to PrimeFaces.

So AngularFaces 1.0 was an interesting study, but little more. It felt like a dead end, even if it worked pretty good.

At the end of 2013 Thomas Andraschko (one of the PrimeFaces committers) proposed to write a differential JSF AJAX engine. He had observed that most AJAX requests replace parts of the DOM tree that don't need to be replaced. In some cases this behavior even causes errors. He proposed to analyze the AJAX response, compare it to the DOM tree and to deliver only the differences to the client. I'd already done a similar thing in the past, so I started work on BabbageFaces. I expected it to be a matter of weeks, but in the end I spent a couple of months with BabbageFaces. It's surprising how many different kinds of JSF AJAX responses exist. Judging from my readers' feedback, I've managed to do it right in the end, but truth to tell, I'm not sure I've found every possible constellation. Yesterday I've called it a version nonetheless and put it on Maven Central, too.

The surprising thing about BabbageFaces is people are interested in such a thing. Even JSF Spec lead Ed Burns wrote a tweet about it. The key feature of BabbageFaces it to reduce the load on the network. Is network traffic (being a crucial aspect of performance) a major point of pain in many projects?

So I started to tackle the idea of AngularFaces from another angle. Rudy de Busscher has this nice AngularPrime (now AngularWidgets) project. He offers a set of rich client-side components that follow the look and feel of PrimeFaces components. Plus, they require less code. I decided to write a couple of JSF components that don't generate tons of HTML, CSS and JavaScript code, but the more compact AngularPrime code.

Another interesting idea came from a reader of mine, Cliff Lo. He proposed to integrate AngularFaces with the Dart programming language. I ended up porting AngularPrime to Dart. That was a lot of fun, and I'm still sure it's a good idea. The weakness of this approach is AngularDart. Don't get me wrong: AngularDart is just great, a lot better than AngularJS in my opinion. They claim AngularDart is sort of a preview to AngularJS 2.0. If that's true, AngularJS 2.0 is going to be great. Problem is, AngularDart is still under development. I stopped work on AngularPrime/Dart when the AngularDart team committed a breaking change - and announced to do more breaking changes in future.

Time to take a break. I think it's better to resume work on AngularPrime/Dart when the dust has settled.

Then there was this JAX conference panel discussion with Mark Struberg about the new HTML5 style of JSF. He said many developers (and web designers in particular) don't like heavyweight JSF component libraries. They make the job of a web designer a pain. Why don't you just use simple HTML5 tags and add some JSF sugar here and there?

Well, that didn't match the idea of AngularPrime. As I mentioned before, I'm still convinced client side widgets are a very good idea, but by the look of it I started to drive too many developers away from AngularFaces. Even if there's a lot of interest in Dart the majority of Developers still uses good old Javascript (and many of them have grown very fond of it, so Javascript is definitely here to stay). Plus, web designers wouldn't be to happy with the tedious task of styling my overly complex components. Java 8 wouldn't help, either. Three key decisions to correct. Just how?

Speaking of the JAX, I felt very flattered when I attended a talk about JSF and Javascript. All of a sudden, Andy Bosch mentioned AngularFaces. Thanks, Andy! He also mentioned that JSF and AngularJS aren't compatible at all because both claim to be the owner of the DOM tree. How true. That's a fourth thing to take into consideration, and it has led to the new AJAX engine of AngularFaces. AngularFaces 2.0 doesn't ignore the mismatch between JSF and AngularJS. It makes it a virtue.

Reza Rahman added another challenge when he mentioned AngularFaces at Oracle's aquarium. He write "It combines JSF and AngularJS in a way that almost makes it look too easy." Exactly. Simplicity is the principal goal of AngularFaces. AngularFaces 1.0 wasn't bad, but I still wasn't satisfied with the programming model. There must be a way to write a JSF page that almost can be mistaken for an AngularJS page.

As it turns out, this is possible indeed.

The saving idea

Some six weeks ago I noticed it's possible to manipulate JSF components before rendering. I already knew it's possible to insert JSF components to the JSF tree on the fly (see Safely manipulating the component tree with JSF 2, revisited). It's not very reliable - JSF tends to re-order your JSF components after a post-back request in unexpected ways - but it's possible. The key idea was not to add a component, but to modify the attributes of an existing component and to replace the JSF expressions by AngularJS mustaches. Plus, I'd add the code supporting AngularJS on the fly as part of the rendering phase. Sounds like a dirty hack? Yes, it is. But it works. During the last month I worked out the idea, threw the component library away (or rather: I saved it in the attic for later use), added most features of AngularFaces 1.0 again, wrote a couple of examples to explore the idea and wrote the tutorial on AngularFaces.com.

By the way, in the meantime I've been able to remove the ugly hack by a better solution: a custom TagDecorator (more on that in a future article). AngularFaces 2.0 has a rock-solid technical base that should be well prepared for JSF 2.3 and above.

AngularFaces 2.0

Last week I finished work on AngularFaces 2.0. After running a couple of tests I put it on Maven Central yesterday. I've already written a lot about how to use AngularFaces 2.0 in other articles (most notably the AngularFaces tutorial at

AngularFaces.com), but also AngularFaces 2.0 Embraces Both HTML5 and PrimeFaces), so suffice it to summarize the differences to the last release candidate here:

  • AngularFaces 2.0 now has a rock-solid technical basis. I removed the original hack that might have been broken in future versions. The drawback is you have to add a context parameter in your applications web.xml to make AngularFaces work: javax.faces.FACELETS_DECORATORS de.beyondjava.angularFaces.core.tagTransformer.AngularTagDecorator If you forget to add the parameter: AngularFaces reminds you. I want it to be a friendly framework :).
  • Performance has improved significantly. As is so often the case, I've already a couple of ideas to improve performance even further. But I believe even large JSF pages should run smoothly with the current version of AngularFaces.
  • Labels and messages generated automatically be AngularFaces are client-side widgets now. So the labels are displayed red as soon as AngularJS detects a validation error.
  • Now you can use AngularFaces without PrimeFaces. Of course, it's still possible to use AngularFaces with PrimeFaces. But it's an optional (albeit highly welcome) library now.
  • There's a new tag, <ngsync>, that allows you to bring arbitrary JSF bean attributes (even complex objects) to the AngularJS model. In a future version <ngsync> will also implement the other direction (sending arbitrary data from the client to the server).
  • ngvalue has vanished. The custom TagDecorator makes it possible to always use the traditional attribute "value" of JSF.
  • As mentioned before, AngularFaces 2.0 is available on Maven Central. Simply add the dependency to your pom.xml: de.beyondjava angularFaces-core 2.0.0
  • The jar file at Maven central has been compiled with Java 6. It should even be compatible to Java 5, but I didn't want to compile it with Java 5 because of the performance penalty. However, feel free to compile your own Java 5 version from the sources on GitHub.

What's not in the version

There are a few important features I postponed until the next version AngularFaces 2.1:

  • The most important feature is finishing <ngsync>. Currently, it only supports one direction. The next version of AngularFaces will also make it possible to send data back to the server. In the meantime you can simulate the feature by using a hidden <h:inputText> and parsing the data in the setter of the corresponding JSF bean attribute. By the way, there's an example at the project GitHub repository showing a way how to send data to the client using the JSF Javascript API. But I don't recommend this particular solution: it feels like a hack. Over the years I've learned to trust my gut feelings, so chances are there's something wrong with the solution of the example.
  • Global error messages and <prime:growl> aren't supported yet.
  • You can combine traditional AJAX requests with AngularJS, but only if you use PrimeFaces. Maybe I'll find a fix for Mojarra and MyFaces as well (albeit I'm not very optimistic).
  • One of the key features of AngularJS is routing (splitting an HTML page to several smaller pages that are loaded dynamically). AngularFaces should support this as well. Probably this feature won't make it into version 2.1.
  • Another feature postponed until 2.2 or later is the Dart integration.

AngularFaces-Widgets

The widget library of AngularFaces 1.0 has become a separate library in the incubator folder of the project. On the long run the widgets are very interesting because they reduce network traffic and make your application more responsive, so I'll restore compatibility to AngularFaces 2.0 sooner or later..

Manual and showcase

There's a tutorial on AngularFaces.com.

The showcase showcase.AngularFaces.com hasn't been updated yet. It still shows last year's AngularFaces 1.0. Stay tuned!

License

AngularFaces 2.0 is published under a GPL 3 license. Strictly speaking, this may limit legal commercial use. Please contact me if that's a issue to you, so I can grant you a license that suits your needs better.

Kudos

I've already mentioned a lot of people who've helped me to finish AngularFaces. Some of them directly, some of them indirectly, by writing a tweet or an article. But I know I didn't mention everybody who made AngularFaces popular. There are countless tweets. 43 people starred the GitHub project. 15 people even forked it. Amazing! Even such a small action like clicking the GitHub star is valuable feedback to me (it shows you're interested in the project). Thanks, everybody!

Feedback and contibutions

Feedback, suggestions, contributions and even issues on the bug tracker are always welcome. Feel free to write a comment or to create an issue on the GitHub repository.

Now there's only one thing left to say:

Enjoy!


AngularFaces.com

AngularFaces 2.0 Embraces Both HTML5 and PrimeFaces

AngularFaces: AngularJS Puts JSF on Steroids

AngularFaces GitHub repository


Comments