Monday, 21 January 2013

Comparison between AngularJS and JSF

Introduction

Although AngularJS and JSF are completely different frameworks at first sight, they have a lot of similarities.
When I was looking for a framework a couple of months ago, to do some web development with JavaScript, I stumbled by accident on AngularJS.
And immediately when I looked at the home page of the framework, it felt very familiar with JSF which I'm already doing for more then 5 years now.
And although my knowledge of JavaScript is very minimal, I was able to create a very simple application which uses a controller, a services, a partial html file etc...
Because the concepts are almost identical and for the JavaScript syntax, I had a peep in some other example applications.
By now, I realize that there are a lot of JavaScript frameworks that are doing more or less the same as AngularJS but for me, having a JSF background, AngularJS is the most natural choice.
I recreated the example I made for my previous blog entry in JSF so that you can see the similarities even better. Code can be found on GitHub.

Comparing view

The first similarity is the way how the view is defined.  Both are (x)html files where you define with html tags the structure of your page. And with some markers/tags you add information to include the dynamic data or parts.
Below the examples
<h:form id="name-form">
        <p:panel id="panelTitle" header="Names list">
            first name <p:inputText id="firstName" value="#{personView.person.firstName}"/>
            <br/>
            last name <p:inputText id="lastName" value="#{personView.person.lastName}"/>
            <br/>
            <p:commandButton id="saveBtn" actionListener="#{personView.save}" value="Save" ajax="false" />
        </p:panel>
        <ui:fragment rendered="#{not empty personView.list}">
            <ul id="names-list">
                <ui:repeat value="#{personView.list}" var="person">
                    <li>
                        <div class="view">
                            <label><h:outputText value="#{person.firstName} #{person.lastName}"/></label>
                            <p:commandButton styleClass="destroy" actionListener="#{personView.deleteById(person.id)}"
               ajax="false" id="removeBtn" value="?"/>
                        </div>
                    </li>
                </ui:repeat>
            </ul>
        </ui:fragment>
    </h:form>
    <p:growl showDetail="true"/>


and for AngularJS
<section id="namesapp" ng-cloak>
  <header id="header">
    <form id="name-form">
      <div ng-controller="NamesCtrl" id="">
        <div id="panelTitle" pui-panel title="Names list">
          first name <input id="firstName" ng-model="firstName" type="text"/>
          <br/>
          last name <input id="lastName" ng-model="lastName" type="text"/>
          <br/>
          <button ng-click="addPerson()" type="button">Save</button>
          <ul id="names-list">
            <li ng-repeat="person in data">
              <div class="view">
                <label>{{person.firstName}} {{person.lastName}}</label>
                <button class="destroy" ng-click="removeName(person)"></button>
              </div>
            </li>
          </ul>
        </div>
      </div>
    </form>
    <div id="growl"></div>
  </header>
</section>



At first glance, the AngularJS version looks more like regular HTML then the JSF version.  The JSF version uses quit a lot of tags from the PrimeFaces component library.  This means that you see the specific tags of it like <p:commandButton>.
With the AngularJS version, you see only the custom directive pui-panel on the div tag.  Custom directives can also be defined as using elements in the page.  So I can define the PrimeUI panel as <pui-panel ..> which results in almost identical tags as with JSF.
And in a later version of the integration between PrimeUI and AngularJS I have also the custom directives pui-input, pui-button and so on.
So for me, defining the view in AngularJS and JSF is identical.

Comparing expressions

AngularJS and JSF have both a kind of expression language to mark the places where the dynamic content must be inserted. Within JSF you have #{} where as AngularJS looks for {{}}.  Besides the notation who is very alike, there are some differences.
Within AngularJS, you define the controller seperately, with the ng-controller directive.  With JSF, you specify the managed bean within the expression itself.  This means that you have greater flexibility with JSF and your managed beans are more fine grained then the AngularJS controller.
I find also the usage of the expression markers, the {{}} and #{}, is more consistent within JSF.  When using the directives ng-model, ng-repeat, etc ... the {{}} marker isn't needed because AngularJS evaluates the string.  But this makes it less readable for a novice as me. You need to know that the string placed in directives are some variables defined in a controller which is defined in some of the parent tags.

Controller versus Managed bean.

The AngularJS controller and the JSF managed bean are very similar.  Of course, they are written in another language but both have the same architectural role. They are both referenced from the expression language, they buffer the values for the screen and they contain the methods referenced from the on-click of the buttons.
The actual work is in both occasions delegated to some services injected into the controllers.

AJAX

The partial page updates is one of the major differences between the frameworks. With JSF, by default the page is completely rebuilded after each post to the server.  With the versions 2.x there is support for partially updating the page.  But you have to specify it on every place where you like to use it. This is in contrast with AngularJS where the values of the expression language is updated after every 'event'.
So for example, when you start typing in an input field with the ng-model directive, all the expressions in the page, the watches, are checked to see if they need to be updated.  Of course, this gives the user maximal responsive applications but can lead to a performance issue when you have a lot of those expressions/watches in your page.  But according to the documentation, 1000 should be no problem what is sufficient for normal applications.

AngularJS application generation

Due to the analogy between the 2 frameworks, I started playing with the idea that I could take a JSF application and 'compile' it to the AngularJS version.
I knew that it wouldn't be easy but started in a good spirit and defined some new JSF tags that where needed.  My page looked something like this:
<r:app>
  <h:form id="name-form">
   <r:controller library="person" url="personList" handler="#{personService.loadAllPersons}" alias="persons"
        <ui:fragment rendered="#{not empty persons}">
            <ul id="names-list">
                <ui:repeat value="#{persons}" var="person">
                    <li>
                        <div class="view">
                            <label><h:outputText value="#{person.firstName} #{person.lastName}"/></label>
                            <p:commandButton styleClass="destroy" actionListener="#{personService.deleteById(person.id)}"
               ajax="false" id="removeBtn" value="?"/>
                        </div>
                    </li>
                </ui:repeat>
            </ul>
        </ui:fragment>
    </r:controller>    
  </h:form>
  <p:growl showDetail="true"/>
</r:app>
With the controller tag, you would be able to define the URL on which the JAX-RS rest would be configured (here /person/personList), the method of the CDI bean which should provide the data and the alias under which this list is available for the expression language.
Besides the generation of the AngularJS HTML file, it is also the intention to generate the JAX-RS classes that handles the communication with JSON data.
Now that I'm a few months further, I realize that my target was set too high. A lot of things are already working like
  • A custom ELResolver to support the alias created in the controller app
  • A JSF preview, so that you can run the JSF application which contains the app and controller tags.
  • The generation of the AngularJS HTML page and javascript files.
  • Basics of the JAX-RS classes generation
  • A maven plugin with a 'compiler' that takes a JSF maven app and creates a AngularJS maven app.
But a lot more work need to be done before it is useable.  And since I don't have that much spare time, I decided to postpone this idea and focus on other topics of the StatelessPrime idea.

In one of the next blog posts, I can present you a way to integrate JSF and AngularJS application in a single web page. And with integrate, I mean that JSF calls AngularJS controller methods and AngularJS code calls JSF backing bean methods.

Conclusion

Of course, JSF which is mainly a server side framework is different from AngularJS, a JavaScript framework for the browser.  And they target also different kind of web applications.  Both they are surprisingly alike in defining the html output and the concepts.

So someone who is familiar with JSF can learn very quickly AngularJS and vice versa.

24 comments:

  1. Interesting article, however I have hard time to understand how JSF and Angular could be complementary technologies... As I understand it, when you're doing JSF you want to encapsulate all client side tech (tags,script) in server side components. So if you know how client side tech works (tags,css,script), you'll only need a thin server side tech like JAX-RS. Why would you want to talk to the 800 pounds JSF gorilla?

    ReplyDelete
    Replies
    1. 800 pounds - funny but so true.

      Delete
    2. How safe is Javascript from being hacked, say on site where security is lot more important than Single Page interactivity ? Have anyone ever look at Security angle when compare Server Side technology (JSF) to Browser Side techology (Javasript/Angular) ? Let say you write very secure software for the Pentagon, can you risk using script that can be hack and insert on Browser side ?

      Delete
    3. This comment has been removed by the author.

      Delete
    4. http://www.slideshare.net/jgrahamc/javascript-security-2064979?related=1

      Author Conclusion: Deprecate javascript due to security

      http://www.veracode.com/security/javascript-security
      http://www.slideshare.net/johannhartmann/javascript-security-27779381?related=2
      http://www.slideshare.net/orysegal/clientside-javascript-vulnerabilities
      http://www.jscripters.com/javascript-security-breaches/

      Delete
  2. As said in the conclusion, they targets different types of web applications and integration is not the common usecase indeed. But as far as I know AngularJS at this moment, the validation of input values is much powerful in JSF.
    And JSF is indeed a lot heavier but is much lighter then you may think. JSF is also no longer a complete server side framework, take for instance a look at PrimeFaces where the screens are mainly created by JS and JQuery.

    ReplyDelete
    Replies
    1. For past few years I've been working only with jsf and have this thought:
      Single page app kills jsf.
      Angular is no doubt superior in such case. Oh, and that ViewExpiredException...no comment.
      On the other hand it's way easier and faster to create pages full of inputs with all kind of crazy validation rules.

      Delete
  3. Also other people are seeing the similarities and complementary functionality. See for example AngularFaces at http://www.beyondjava.net/blog/angularfaces-jsf-beyond-ajax/

    ReplyDelete
  4. Thank you for this great article I also come from JSF world and I am torn apart between those two frameworks.
    In Angular I miss templating and internationalization. It also takes time to develop API where you need to be extra careful with data you expose.

    ReplyDelete
  5. What i find interesting in angular, and how it is syntactically similar to JSF is that JSF could well be interpreted in client side with a library similar to angular. You could then code your entire app in JSF, then depending on your bandwith, local machine performance, and software usage execute no, part or all the code could be executed on client or server side : no need to bother where it is executed, the runtime will decide it for you.
    Add to this that webrtc/datachannel will replace the client/server paradigm with P2P and you get really nice things coming.

    ReplyDelete
  6. There is no way how jsf can be better than angular. Worked since 2006 with this broken framework and very glad its dying after all.

    ReplyDelete
    Replies
    1. Everything has his pro and contras and where it shines.
      But JSF is not broken and not dying (more and more customers are switching to it!)

      Delete
    2. Again, it is an 800 pound gorilla.

      Delete
    3. And the Hello World in AngularJS 2 takes 117Mb. How much does that Elephant weight? :) https://twitter.com/cagataycivici/status/687250780659802112

      Delete
    4. This comment has been removed by the author.

      Delete
    5. I love how every time google fails against Java Community first they tried with gwt then AppEngine now angular.
      And there are a subjects where google was better before like Bigtable vs Hadoop. They lost data tier then app tier and now they are going to lose prenstation. Only thing left for google is Mobil which they look like undefeatable there unless ubuntu touch community and Java Community starts working together.
      Yes JSF needs more Ajax, javascript for asynchronicity, reactivity but js frameworks (angular, react ...) cant compete with productivity of jsf.

      The only possible obstacle for java world is Oracle itself by the way take a look at this :

      https://javaee-guardians.io/

      Delete
    6. I know the Java EE Guardians; I'm part of it :)

      Angular will have some good use cases and benefits. Like for example the usage in Ionic framework so that you can create cross platform apps.

      Delete
  7. Have anyone ever look at Security angle when compare Server Side technology (JSF) to Browser Side techology (Javasript/Angular) ? Let say you write very secure software for the Pentagon, can you risk using script that can be hack and insert on Browser side ?

    ReplyDelete
    Replies
    1. Using Https and proper authentication can do a lot and obfuscating the JavaScript of course.
      I don't think there are much differences in security requirements.
      And what happens in your browser isn't the most important thing, it is protecting the data in the backend.

      Delete
    2. This comment has been removed by the author.

      Delete
    3. http://www.slideshare.net/jgrahamc/javascript-security-2064979?related=1

      Author Conclusion: Deprecate javascript due to security

      http://www.veracode.com/security/javascript-security
      http://www.slideshare.net/johannhartmann/javascript-security-27779381?related=2
      http://www.slideshare.net/orysegal/clientside-javascript-vulnerabilities
      http://www.jscripters.com/javascript-security-breaches/

      Delete
  8. take a look @ http://bessemhmidi.github.io/AngularBeans/

    ReplyDelete
  9. Still JSF2.2/PrimeFaces better from any framework. Angular can be part of web project, but cant play main role.

    ReplyDelete