Handling DWR responses

3 min read >

Handling DWR responses

Engineering Insights & Enterprise solutions

Seeing this thread on the DWR mailing list, I thought I’d post one way to deal with DWR response. The actual problem was initiated by someone asking what’s the best way to display status messages to users using DWR.
Lance Semmens describes a solution using a template like:

public class Result<T> {
private boolean success;
private T successObject;
private Map<String,List<String,String>> messages;

// getters and setters
}
The object obviously needs a DWR converter so that it can be converted to javascript. When an instance of this class gets returned to the js code, the function must check if the operation has been successful and display any errors included in the Result object.
The problem with this approach is that every javascript function used as a DWR callback needs to have the same piece of code:
if(!obj.success) {
// display error messages
}

The object obviously needs a DWR converter so that it can be converted to javascript. When an instance of this class gets returned to the js code, the function must check if the operation has been successful and display any errors included in the Result object.
The problem with this approach is that every javascript function used as a DWR callback needs to have the same piece of code:


if(!obj.success) {
// display error messages
}

When maintaining a large number of DWR callbacks, maintaining the same code in all DWR callbacks is obviously not a choice. Wouldn’t it be useful to have some sort of AOP interceptors for every js callback, dealing with the error messages in a unified and transparent manner? For this, I’d suggest using something similar to the dojo’s event system to intercept all callbacks and handle success cases in a unified manner. If you don’t use dojo, here’s some sample code to intercept all DWR callbacks (more specifically – all methods prefixed with “DWR”).


<html>
<head>
<script>
dwrCallback1 = function(response) {
alert(“fn1: further processing … (” + response.success + “)”);
}

dwrCallback2 = function(response) {
alert(“fn2: further processing … (” + response.success + “)”);
}

dwrCallback3 = function(response) {
alert(“fn3: further processing … (” + response.success + “)”);
}

init = function() {
var m = getMethodsWithPrefixForObject(window, “dwr”);
for (var i = 0; i < m.length; i++) {
attachHandlerBefore(window, m[i]);
}
}

attachHandlerBefore = function(obj, methodName) {
obj[“_” + methodName] = obj[methodName];
obj[methodName] = function(response) {
if (response.success) {
alert(response.msg);
}
obj[“_” + methodName](response);
}
};

getMethodsWithPrefixForObject = function(obj, prefix) {
var methods = [];
if (typeof obj == “object”) {
for (var prop in obj) {
var tmpObj = obj[prop];
if (tmpObj == null || typeof tmpObj == “function”) {
if (prop.indexOf(prefix) == 0) {
methods[methods.length] = prop;
}
}
}
}

return methods;
};
</script>
</head>
<body onload=”init()”>
<button type=”button” onclick=”dwrCallback1({success:true, msg:’User details saved successfully’})”>Sample response 1 – through DWR call</button>
<br/>
<button type=”button” onclick=”dwrCallback2({success:true, msg:’Password has been changed’})”>Sample response 2 – through DWR call</button>
<br/>
<button type=”button” onclick=”dwrCallback3({success:false, msg:’Username must contain only letters!’})”>Sample response 3 – through DWR call </button>
</body>
</html>

In addition to this mechanism, all exceptions can and should be caught using DWREngine.setErrorHandler.