Tuesday, June 11, 2013

Ext-JS: Form Submit always returns to the failure block

Got late in writing today’s post.
I was busy watching the India vs West Indies cricket match of the Champions Trophy. Well it was a good match and glad India won it quite convincingly in the end.
India winning the match against WI
thanks to Jadeja and Dhawan


It was a pleasant day at the office today overall for me. No major hiccups but this one thing was really troubled me for quite some time. 

I had an ExjJs form where I was uploading an excel file to the server, processing it and sending success/failure messages back to the client. 

When I wrote the code I went with an assumption that if any error occurs at the server (while doing the IO operations on the file), the control will automatically reach the “failure” handler of the AJAX call. Otherwise, it will execute the code inside the “success” handler.

Turned out the control always reached the failure handler even in case of successful processing! Quite baffling to me at first. 

But later I realized that the AJAX call requires a “success” parameter (Boolean) inside the response from server. The value of this parameter will determine which handler to invoke.

So this is what I did. 
Now please note, there may be many other better ways to handle this. 

So my form.submit method looked like this:

 form.submit({  
      url : 'url_to_call_Action_method?fileName='+ Ext.getCmp("FileControl").value,  
      data : {  
           fileName : Ext.getCmp("FileControl").value  
      },  
      // success handle  
      success : function(fp, o) {   
           //Parse the JSON string, in case of success, returned inside the response object  
           var flds = JSON.parse(o.response.responseText);  
           // do further operations  
      },  
      //failure handler  
      failure : function(fb, o) {  
           //Parse the JSON string, in case of failure, returned inside the response object  
           var flds = JSON.parse(o.response.responseText);  
           // show error to the user  
           ShowExtError(flds.errors);  
      }  
 });  

Now in case of success what I was expecting in return from the server was something like this:

 {"cols":[
         {"header":"request_id","dataType":"Integer","fieldFound":false,"seq":1},
         {"header":"employee_code","dataType":"Integer","fieldFound":false,"seq":2}
        ]
}  

But like I mentioned the control was always going inside the "failure" block and never in the "success" block.

So this is what I did:

In my Java (Action) class I explicitly {"success" : true} in a map object in case of successful processing of the file

 Map map = new HashMap();  
 map.put("success", true); //explicitly setting success = true  
 map.put("cols", headers); // my cols object which I was expecting at the client  
 Gson gson = new Gson(); // created a temporaray Gson object  
 String str = gson.toJson(map); // converted map to JSON string  
 response.setContentType("text/html; charset=UTF-8"); // set the content type  
 response.getWriter().print(returnMsg); //write the JSON string to be returned  

And if there was any error/exception while processing I set the success parameter to false. Like this:

 Map map = new HashMap();  
 map.put("success", false);  
 map.put("errors", "File not found in the specified path.");  
 // create GSON, parse and set the string into the response writer  

That’s it. Now the control reached the designated handlers perfectly file.

In case of Success I got the following JSON string as the response:

 {"success":true,
 "cols":[
       {"header":"request_id","dataType":"Integer","fieldFound":false,"seq":1},
       {"header":"employee_code","dataType":"Integer","fieldFound":false,"seq":2}
       ]
}  

And in case of failure, this:

 {"success": false, "errors":"File not found in the specified path"}  

So next time, if you happen to face a similar issue just remember "success" parameter has to be set in your response text.
It only depends on you how you do it!

Please post your comments and valuable suggestions and better alternatives to this.

2 comments:

  1. Hi,
    I prefer to use Ext.decode to parse Json instead of JSon. Are there any reasons else?

    ReplyDelete
  2. There is nothing wrong with using Ext.decode() to parse your JSON but it is advisable to use the native JSON.parse() methods.

    Go through the comments of my one more post on JSON parsing here:
    http://atechiediary.blogspot.com/2013/06/javajsextjs-convert-serialize-java.html

    ReplyDelete