23 Mar 2015

AngularJS initial data load + Jersey

Resume: there are several apps I’ve seen developed on AngularJS that seem pretty slow. This apparent slowness comes from the fact that JS developers use REST calls after the first load of the page which is another round trip to the server. So how do we fix this issue?

ng-bind directive

Which means that instead of

<p>{{variable}}</p>
you’re going to use a more verbose syntax:
<p ng-bind='variable'>$defaultValueCameWithHtmlPageServer</p>
The verbosity is not a problem as for me - it looks pretty fine. But what’s more important - you get 2 different ways of putting data into the HTML page: AJAX + REST and also initial JSP/Velocity/Whatever. In both places you may have bugs so 2 things to test and support.

Initially populated JS

But there is a better way described on SO. We create a function that can accept the data:

$scope.initialize = function(json) {  $scope.data = json; };
And then populate this function on the HTML page:
<body ng-controller="MainCtrl" ng-init="initialize( { field: 'value' } )">
So you have to generate the same JSON as you would send back in AJAX response and put it directly into HTML page.

Server Side

One problem left - how to accomplish this on the server side. With Jersey I could come up with this (a big ugly, but working) solution:

StringWriter writer = new StringWriter();
ObjectMapper mapper = new JacksonJaxbJsonProvider().locateMapper(Object.class, MediaType.APPLICATION_JSON_TYPE);
mapper.writeValue(writer, someRestService.getSomeResource().getEntity());
String json = writer.toString();

So in your Controller you trigger the very same REST Service, get its results and convert them into JSON. Afterwards you can pass this variable to the JSP/Velocity/Whatever page.