Wednesday 4 December 2013

Grails 2.3 REST improvements and AngularJS $resource problems with delete

The Grails 2.3 version introduced some nice REST improvements - it is now very easy to generate RESTful endpoints for your data model. I was also very happy to discover that handling business logic rules is nicely supported by overriding just a few core methods (e.g. queryForResource, listAllResources and so on - take a look at the RestfulController documentation).

So when I tried connecting this backend to the AngularJS $resource service, most of the things worked beautifully, with the exception of delete calls: a delete Ajax call would always get returned as a redirect request. This would make Firefox issue a prompt to the user if they really wanted to follow that redirect, which is the wrong behaviour and something the user should not have to decide about anyway.

What gives? Taking a look at the RestfulController source the relevant parts of the delete method are implemented like this:

request.withFormat {
        form {
                flash.message = message(code: 'default.deleted.message', args: [message(code: "${resourceClassName}.label".toString(), default: resourceClassName), instance.id])
                redirect action:"index", method:"GET"
        }
        '*'{ render status: NO_CONTENT } // NO CONTENT STATUS CODE
}

The first thing one should be careful about is that request.withFormat does not do the same thing as withFormat: the later parses either the Accept HTTP header, the ?format= parameter or the format= directive in the URL mappings while the former looks at the Content-Type header only. I lost a bit of time on this because I didn’t read the withFormat documentation carefully enough.. my bad.

So the issue was with AngularJS not setting the Content-Type header for DELETE requests and Grails interpreting the request as a HTTP form request for which a redirect is the most sensible action. This behaviour on Grails' part is a bit odd since DELETE requests aren’t supposed to contain any content and therefore don’t require Content-Type to be defined - on the other hand depending on the Accept header has problems of its own since browsers seem to send strange things in it. Fine, I’ll just define Content-Type in the AngularJS request and be done with it.

But it turns out that’s not so easy! There are several ways to set Content-Type in a $resource request like using a transformRequest function or a headers option (which is not documented clearly enough in my opinion). None of these work that simply! Why? There’s an issue recorded for AngularJS that gives us the answer: the gist of it is that some browsers do funny things to Content-Type in case of requests without a body, such as a DELETE request.

So the final solution was to send a small body with the delete request, like so:

_this.resource('..url..', { id: '@id'}, {
        remove: {
                method: "DELETE",
                isArray: false,
                headers: {
                        'Content-Type': 'application/json'
                },
                data: {}
        }
});

I’m hoping for smooth sailing after this - AngularJS and Grails' REST improvements seem like a match made in heaven :)

Wednesday 19 October 2011

Grails doing unexpected Hibernate selects when checking if lazy properties are null

So this bug cost me several hours of my precious time. I had to check if a member of a GORM entity is null or not without lazy loading that same entity. Turns out it is not very simple, nor is it intuitive. Doing a simple
if (object.property == null) {..}
triggered a Hibernate load. A working solution is explained here: you have to do
if (object.propertyId == null) {..}

I cannot find this in the documentation but as the docs are huge, I may have very well missed it.

Tuesday 18 October 2011

Thoughts on Dart

I have to say I disagree with the article on Dart that appeared on Quirksmode.

The author argues that Javascript has already 'won' and Dart has 'lost' because there are billions of Javascript-capable devices available today. I think it's the wrong comparison: in the short term, Dart isn't competing with Javascript, but rather with these guys! To name just a few famous ones: CofeeScript, ClojureScript, GWT. Dart is much less efficient than all of these guys right now, but it isn't like Google to fall into the premature optimization trap so I expect some serious improvements on this front.

The article also states that Dart is a result of "disdain that "real” programmers feel for JavaScript". Javascript is the ugly duckling that required plastic surgery to turn into a swan. Sure, it has a few nice tricks up its sleeve to alleviate the sucky parts, but many of those same tricks are preventing both its efficient optimization as well as its maintainability. That list of the 100+ languages that compile to Javascript should give us a hint that Javascript isn't Mr. Perfect. And don't get me started on its standard library: just thinking about Javascript's date handling or internationalization support (no, we're not all American) gives me a nervous twitch! If by "real" programmers QuirksMode means the guys and gals who have to write and maintain non-trivial applications that work well on several continents, who move to a different job and find that their new employer is using jQuery instead of Prototype, these non-rockstar developers _should_ hold a disdain for Javascript.

I think in time Dart's place in mobile will become better defined. Either the general public is not in the loop or maybe Google hasn't decided yet, but I can think of at least two scenarios and I'm sure there are more options:

  1. Google switches Java for Dart as the main Android development language: it's not such a far stretch given the Oracle lawsuit and Java's rigidness when it comes to fast prototyping (the thing projects like Groovy and Clojure are trying to alleviate) 
  2. Google creates either an Adobe Air-like container or a PhoneGap style compiler for Dart apps that runs on all the major mobile platforms

Nothing lasts forever. COBOL and Fortran aren't hot stuff anymore and Javascript is far from perfect. I don't know who or when will topple the king, but Google doesn't want to meet the same fate on the web that Microsoft did with tablets. It's seeing chinks in Javascript's armor and it's ready now with talent that has built V8, Dalvik and the like. If Dart fails Google will try again and again but I wouldn't count the new language a default loss just yet.

Tuesday 14 June 2011

Two nice Groovy design patterns

Putting my deep SQL and HSQL roots on hold I took advantage of Hibernate Criteria (via the excellent Groovy builder for super readable code) to safely generate a dynamic query today. I stumbled into two problems:
  1. how to keep things DRY - can I avoid rewriting the same query multiple times when simple things change?
  2. how can I elegantly query associations whose names I do not know in advance?
I was able to resolve both issues quite satisfactory.

Keeping queries DRY

My first attempt was to create a basic query structure as a Groovy closure and then modify it at runtime as the exact query would be known. Couldn't make it work. Fortunately, the second attempt was more successful: I used a simple factory pattern to create the closure dynamically before feeding it into the Criteria Builder:
def createQuery = { Boolean discriminate ->
	 return {
	 	 projections {
	 	 	 sum "property"
	 	 }
	 	 if (discriminate) {
	 	 	 idEq 42
	 	 }
	 }
}
MyClass.createCriteria().list(createQuery(false))

Choosing associations dynamically

In order to reference an association, you have to use its name in the closure as a method call with a closure as the parameter. Suppose you have the name of the property in a string object, how do you call it as a method in the closure ? Using evals could've worked, but that would present a serious security risk. Groovy's GStrings to the rescue:
def discriminateProp = params.prop
def discriminateBy = params.val
def createQuery = { Boolean discriminate ->
	 return {
	 	 projections {
	 	 	 sum "property"
	 	 }
	 	 if (discriminate) {
	 	 	 "${discriminateProp}" {
	 	 	 	 	 idEq discriminateBy.toLong()
	 	 	 }
	 	 }
	 }
}
MyClass.createCriteria().list(createQuery(true))
I still have to wrap my brains around possible security risks of this approach, but at the first glance it seems solid.

Tuesday 7 June 2011

Simulating native Javascript events

I just solved an issue that's been bugging me. When creating Javascript unit tests, I would like to trigger native DOM events. I'm using jQuery and despite what their API documentation says, some events not bound via jQuery cannot be triggered with the standard jQuery commands. So after some googling I've found a function that can be included in my unit tests to trigger those events:
window.simulateMouseEvent = function(eventName, element) {
	var evt = document.createEvent("MouseEvents");
	evt.initMouseEvent(eventName, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
	var cb = element
	var canceled = !cb.dispatchEvent(evt);
}
So a sample call could look something like this:
simulateMouseEvent("mouseup", $("#myControl")[0]);

Monday 23 May 2011

Design idea for phones & tablet keyboards

I hate typing on touch devices.

I own an Android phone and an iPad and typing on either is not an enjoyable experience. The iPad's sheer size makes the experience a bit more tolerable, though I hate that there is no feedback when I press a key as this increases my mistake rate. The phone on the other hand does provide feedback by vibrating on keypresses (apparantly the feature's called 'haptic feedback') but due to the cramped keyboard I am forced to edit wrong characters way too often.

One common mechanism for making typing less painful is smart prediction - if the typing mechanism can detect which word I am trying to type and corrects any wrong letters, then I can still type with a decent speed. This has two major drawbacks, however: the language I am using has to be supported & properly selected and uncommon or jargon words can actually take longer to type because I have to outsmart the smart prediction - which (subjectively) seems especially dumb on the iPad.

There are various alternate typing mechanisms available for the Android devices (hooray for an open system that allows experimentation! Boo at Apple!) but so far none have met my expectations - some of them rely on various forms of word prediction and suffer the drawbacks mentioned above while others employ radical redesigns of input methods requiring me to learn new tricks and usually turning out impractical even when I do.

So I was thinking of a rather subtle enhancement to the existing most common input method. Let's assume we can define a small number of short, recognizable vibration patterns and make our mobile device emmit them. About 5 should probably be sufficient. Now let's assign them to keys on a QWERTY keyboard with haptic feedback so that no two neighbouring keys emit the same sequence (this would work equally well on a non-QWERTY keyboard and the vibration patterns could even be assigned algorithmically to support arbitrary keyboard layouts). Suppose that most people would not be bothered by the different vibration patterns and would continue using the keyboard as before. But in time, many would learn to connect specific vibration patterns to specific keys. We wouldn't expect them to know the by heart which key emmits which vibration pattern, but we would expect them to notice "Oh, that didn't feel like an R".

Now comes the only radical design change to the keyboard. We would introduce a correction key. This key would have two requirements: it should be easy to press no matter what hand position you are using and it should not be easy to press another key by mistake. This could be achieved by various means, e.g. by making the key very big or by utilizing one of the physical keys on Android devices (the Search key seems to have no typing related function and even seems a suitably named match). The function of the correction key would be the following: it would remember the last typed letter, but also the next two most likely candidates based on the position at which the finger actually touched the keyboard. When pressing it, the last typed character would be replaced with the next most likely candidate and the device would vibrate the pattern of this replacement character. So the user could think "Ok, now that DID feel like an R" and continue typing. In case that still wasn't the right key, pressing the correction button again would present the second alternative. After this, the list would start looping among the given choices (original guess - first alternative - second alternative) again in case the user accidentally overshot.

Assuming the user isn't a very sloppy typer, the second guess should be correct in large number of cases and the third guess could mop up the majority of situations. As we're not relying on the user's language or keyboard type, this mechanism could be effectively applied to most typing situations. As Android is open source I'm very tempted to find some source code for a simple keyboard and start hacking away, alas time is a commodity in very short supply for me at the moment. This blog post should help me remember my idea if I am ever left with a time surplus but is also a chance for people to give me their comments on the idea, should anyone ever happen to find it.

Thursday 24 February 2011

HTML experiments - hinting line breaks

We had an issue at work today: how do we insert line breaks into long words without introducing any extra characters? The problem at hand was that we had a few long filenames that wouldn't fit into table cells. Browsers break longs words along hyphens, but our filenames contained underscores as well which were good candidates for line breaks in our case. We didn't want to display a filename that differed to the name of the downloaded file in order to prevent user confusion.

We tried a few solutions, including inserting empty <span> elements into the file names, but this only worked in certain browsers. The solution was found in good old Unicode: it has a Zero Width Space character which was exactly what we needed (or so it seemed) - relevant documentation here. In HTML, this character is obtained by using &amp;#x200B;. We would insert one of these after every underscore and voila, long filenames would break where necessary.

As I've hinted above, this solution didn't turn out to our satisfaction - the link's underline would hide the underscores and make the file names look, well, wierd. So in the end we used the very simple solution of substituting underscore with empty spaces. Even though the displayed file name wasn't equal to the actual name of the downloaded file, it sure looked to most users.

Because we engineers want to play with newly discovered toys, I threw together a small Javascript block of code that inserted a zero width space after every letter of text on arbitrary webpages - reading narrow randomly broken columns of text became a headache inducing exercise :)