Tuesday, August 19, 2014

Programmatically Select row in Angular Kendo's Grid

Kendo UI has AngularJs integration. Its mostly working fine but with a few hiccups. One of these hiccups is trying to programmatically select a row in Kendo UI's data grid (call a "grid" in Kendo).

The Kendo grid has a method select(). Which according to the API:
Gets or sets the table rows (or cells) which are selected.
So I tried to call select in a ng-click directive, and I get an error:
$apply already in progress
Some of you AngularJs experts will already know that $apply() is called by AngularJs to apply changes in the model (aka presentation model), to the view (aka presentation). And it cannot be called recursively; ie. you cannot call $apply() while another $apply is already in progress.

So here's a how my code looked like (the code that gave the "$apply already in progress" error):

<button ng-click="selectRow()">test</button>

And in my controller:
$scope.selectRow = function () {
  // ... some code ...
  $scope.myGrid.select( aRow );

After some digging, I found out that almost all code that's in the controller will be in an $apply() call.

  • ng-click="..."
  • ng-blur="..."
  • $scope.$watch(...)
  • $scope.$on(...)
AngularJs docs blame the 3rd party code

Another Problem
And this is Kendo's grid does not have ng-model support. That means you can't do this:

<div kendo-grid

You have to do this:

<div kendo-grid
     k-on-change="selectedRow = data"></div>

So even if I workaround the first problem above, I can't simply do this in my controller and hope the grid selects the row itself:

$scope.selectRow = function () {
  // ... some code ...
  $scope.selectedRow = aRow;

Apparently the accepted way to do it is 
  1. Wrap the data in a kendo.data.ObservableArray object.
  2. Add the CSS class "k-state-selected" to the row.
  3. Manually update the model with the row.

1. Wrap the data in a kendo.data.ObservableArray object
What this does is to provide true binding of each element of the array to each row of the grid. But a secondary effect of this is to wrap each element of the array in a kendo.data.ObservableObject object. This causes each array element to have a uid field automatically generated. And when the Grid renders, it will add a data-uid attribute to the HTML of the Grid row:

<tr class="k-alt ng-scope" data-uid="ac5be667-5483-4c52-bf2a-3a8f85bb5eeb" role="row">


2. Add the CSS class "k-state-selected" to the row

This is done using jQuery:
$scope.selectRow = function () {
    // ... some code
    // "item" now contains the kendo.data.ObservableObject 
    $('[data-uid=' + item.uid + ']').addClass('k-state-selected');

3. Manually update the model with the row

This is done like so

$scope.selectRow = function () {
    // ... some code ...
    $scope.selectedRow = item;

So our final selectRow function looks like this:

$scope.selectRow = function () {
    // ... some code ...
    // "item" now contains the kendo.data.ObservableObject 
    $('[data-uid=' + item.uid + ']').addClass('k-state-selected');
    $scope.workingScreenState.selectedRow = item;

Monday, August 18, 2014

Add cache control headers to Spring MVC

Many times we want browsers and proxies and gateways to cache our static files. But not the data calls. Here's how to add cache control headers in Spring MVC. 

            <!-- Cache of HTML pages -->
            <mvc:mapping path="/**"/>
            <mvc:exclude-mapping path="/images/**"  />
            <mvc:exclude-mapping path="/webjars/**"  />
                <property name="cacheSeconds" value="0"/>
                <property name="useExpiresHeader" value="true"/>
                <property name="useCacheControlHeader" value="true"/>
                <property name="useCacheControlNoStore" value="true"/>

        <!-- Cache of all images  -->
            <mvc:mapping path="/images/**"/>
                <property name="cacheSeconds" value="1800" />
                <property name="useExpiresHeader" value="true"/>
                <property name="useCacheControlHeader" value="true"/>
                <property name="useCacheControlNoStore" value="true"/>
            <mvc:mapping path="/webjars/**"/>
                <property name="cacheSeconds" value="86400" />
                <property name="useExpiresHeader" value="true"/>
                <property name="useCacheControlHeader" value="true"/>
                <property name="useCacheControlNoStore" value="true"/>

This will create the below HTTP headers:

Pragma: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: no-cache
Cache-Control: no-store

This should take care of all the cache problems that we have.

Monday, July 14, 2014

Easy Spring AOP

This article shows how to create aspects in Spring, using Spring AOP.

Quick notes:
  1. Spring AOP is not a fully blown AOP framework (read these few paragraphs). 
  2. It uses AspectJ annotations and pointcut expressions.
  3. Only join point is method execution.
  4. Since Aspects are actually Spring beans, you can inject stuff into it (I prefer using @Autowire for DI).
  5. Spring AOP is a proxy based implementation. This is the most common implementation outside of Spring. Spring will create a proxy for any bean that is being advised. This is called auto-proxying.

Personally always try to use 
  1. Spring's Classpath scanning (aka component scanning)

Ok. To create an aspect I need to:
  1. Create a Spring bean.
  2. Tell Spring that this bean is a Spring AOP aspect
  3. Define the pointcuts. I usually do this in the bean itself, but you can define the pointcuts in its own class.
  4. Define the advices. These will be methods in the bean.

Create a Spring bean
There are many ways to do it. I prefer "annotation-based configuration". So its just a simple annotation (and the xml config to enable annotation-based configuration. I include it here, but its beyond the scope of this document so go read up on it by yourself).

<beans xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <context:component-scan base-package="net.gerardsetho.web"/>


Here is my MyAnnotationClass. Note the @Component annotation
package net.gerardsetho.web;

import org.springframework.stereotype.Component;

public class MyAnnotationClass {

Tell Spring that this bean is a Spring AOP aspect
So Spring now thinks my class is a normal Spring singleton. We need to tell Spring that its also a Spring AOP aspect. There are 2 ways to do it. I prefer to use "@AspectJ aspects", which Spring recognises. This is done by adding a single line in the XML configuration:

<beans xmlns="http://www.springframework.org/schema/beans"

    <context:component-scan base-package="net.gerardsetho.web"/>

    This tells Spring to look for AspectJ annotations in the source code, 
    and create aspects for them.
    It also tells Spring to create proxies for (other) beans which are 
    being advised.


Define the pointcuts
I usually define the pointcuts in the Aspect class itself. I guess one could put them in another class, but I rarely needed to do so.

Defining pointcuts is done using the @Pointcut annotation (its an AspectJ annotation). Note that Spring AOP only understand method-invocation join points. So if you need to advise field-get or field-set join points, you need to use a full fledged AOP framework like Aspect J.

Moving on. I usually like to define a pointcut that matches every method in an advised class. 1 pointcut per class. I think it makes things clearer. Then I make another join point for the methods in the class. The code should make this clear.

public class MyAnnotationClass {

     * Pointcut that describes all join points (in Spring, 
     * the only join points are method invocations)
     * in the class / interface MyController.
    @Pointcut( "target(net.gerardsetho.web.MyController)")
    private void MyControllerMethods() {}

     * any method called home,
     * with any number of arguments
     * which returns anything
    @Pointcut( "execution(* home(..))")
    private void entrypoint() {}


Here are some examples of other types of pointcuts.

Define the advices
We can combine different pointcuts to define an advice. The below combines (logical AND) the above 2 pointcuts, and creates an advice to print to System.out. It uses @Before, but one can use any number of supported advice types.

    @Before( "MyControllerMethods() && entrypoint()" )
    public void logEntryPoints() {

        System.out.println( "logging entry point." );


In addition to other types of advice, one can also access the parameters of the advised methods. Let me know in the comments if you're interested to know about that.

Tuesday, February 25, 2014

Easy Spring MVC, Maven and Intellij IDEA

Its odd that there isn't a Spring MVC Maven archetype. 

But creating a Spring MVC from one of the standard Maven archetypes is easy, and there are many tutorials online to do it. I've done it myself many times. 

I created a video that shows how to do it. I wanted to try to create a skeleton Spring MVC Maven project in Intellij IDEA in 10 minutes (spoiler: I couldn't). I wanted to do it without referring to any online articles or tutorial. So even though there aren't any Spring MVC archetypes, its really easy to do so yourself.

Here's the video:

Thursday, February 6, 2014

Correct way to use DB sequences in JPA

I have a sequence defined in an existing database (mine is PostgreSQL) for the primary key. I want to use JPA (implemented by Hibernate) to use this sequence when persisting (inserting) a new object.

The below is the correct way to do it.

First, basic JPA stuff. The column name.

Next, we need to have 2 annotations @GeneratedValue and @SequenceGenerator. With the former referring to the latter. It looks a little redundant to me, but hey... I'm just a programmer.

Third, we specify the the sequence name (as in the DB). We need to include the schema as well.

Finally, we specify the increment.

ps. I seem to need to restart the server (Glassfish 3) almost each time I make changes to JPA annotations (it was giving me "XxxXxx class is not recognized by Java persistance" etc etc). So if the above doesn't work for you, try restarting the server first.

Friday, January 24, 2014

Creating a Sencha client side app with IntelliJ IDEA and Maven

This assumes you already have a project open in IDEA. I use IDEA 13.

First create a new module. 

Type in a module name.

We will create a module from a Maven archetype (maven-archetype-webapp). In my case, the group id and artifact id aren't important.

IDEA creates the new module for us.

Second, this module will contain a Sencha GXT application, so we need to set up our dependencies. We edit our pom.xml to add in these dependencies. We are dependent on the Sencha jars, and the GWT jars (first 2 red arrows below). We also need the GWT Maven plugin, so we can compile the GWT app from IDEA (the 3rd arrow below).

Below is the text (for copy and paste purposes).

I think its a little irritating that the archetype does not create a java folder for me. So I have to do that. And to tell IDEA that the folder contains all the Java source files and that it should compile all the source files. Doesn't IDEA already know this? Its the standard source location after all... Oh well... We create the folder.

And indicate to IDEA that its a source folder.

(select the module, then select the new folder java, and click the "Sources" button.)

Third, we now add a GWT module (which is basically a Xxxx.gwt.xml file, plus one or more entry point classes). IDEA will create the XML file, and 1 entry point class. If necessary, more entry points can be added later. It also creates an HTML and a CSS file which will load the (GWT-compiled) Javascript which will display the GWT module.

Choose a name for the GWT module.

Fourth, we need to "change" the GWT module to a GXT module. Some Sencha inherits and stylesheets do not work with the standard GWT ones. So we open the Xxxx.gwt.xml file and modify it for GXT (below: red box). Also, I like to add a rename-to attribute. If in the future I add RPC calls to the Sencha app, this attribute will be the URL that the AJAX calls to.

Fifth, most people use GWT development mode to do quick development. To do this in IDEA, we need to create a new configuration. We create a new GWT configuration (and give it any name). Make sure the correct project module is selected (if you have more than 1 like I do). And we also tell development mode to load all our GWT modules. 

We test the configuration: running the configuration will basically start a Jetty server that serves the GWT module (in development mode).
It works.

Finally we add a Sencha widget to make sure this works with Sencha.


Friday, July 5, 2013

Using a Publish-Subscribe messaging pattern in Vaadin

The events system described by the Book of Vaadin is quite primitive. It's a standard Observer pattern (aka Listener pattern). 

Unfortunately, since the Listener requires access to the source object, this makes it highly coupled (the listener has to know about the source). 

What's worse is, in a practical sense, since Vaadin events do not "bubble" (not on the server side at least), its very difficult "get the handler to the required component" without violating all kinds of information hiding best practices.

What we really want is a publish-subscribe architecture that is similar to Parsley's in Flex.

GWT does provide a SimpleEventBus. And Vaadin does include this. And blogger Alex Tretyakov has here a great example of how to use it. As of this writing, its the best example out there.