dojo ajax call using xhr post and json - spring-mvc

I am not able to post a dojo form via xhr call of dojo 1.8 but its happening through deprecated method dojo.xhrPost. Please see the code fragment that I used.
This is portion from jsp for dojo ajax call
require(["dojo/request/xhr"],function(xhr){
xhr('http://localhost:8080/myApp/call',{
data: 'callerName',
method:"POST",
load: function(data, ioargs) {
alert("The message is: " + ioargs.xhr.status);
},
error: function(error){
alert("Returned: " + error);
}
});
});
<form data-dojo-type="dijit/form/Form" name="callerName" id="callerName">
...here are dojo input types
</form>
Below is spring controller
#RequestMapping(value="/call",method=RequestMethod.POST)
public ModelAndView saveData3(HttpServletRequest req, #ModelAttribute Caller caller){}
Here I am not getting the values from form to caller model attribute. but the call is happening.
Instead of this ajax call if I go for deprecated call a below, the values are getting bound.
dojo.xhrPost({
url: 'http://localhost:8080/myApp/call',
form: 'callerName',
load: function(response) {
}
for latest call in 1.8 instead of argument 'data', I tried with 'form' still not happening. What can be this issue?

Dojo has deprecated the load and error callback attributes in favor of deferreds/promises.
Sample of new code with deferreds code below old code with callbacks.
Another sample.
I thought Dojo would maintain backwards compatibility until 2.0, but perhaps it was dropped (ah.. perhaps 1.8 supports the old syntax if you require the old dojo/_base/xhr).
Also, note it is better to require dojo/request instead of dojo/request/xhr directly.
update: Why dojo/request is preferred over dojo/request/xhr:
dojo/request is a higher level abstraction than dojo/request/xhr. So it is:
more portable: dojo/request automatically selects the proper provider and works in both the client and server. dojo/request/xhr will not work on the server (node.js) and dojo/request/node will not work on the client (browser).
more flexible. In the future, perhaps a better provider will be added. dojo/request can use the best provider without any changes to your code. Also, providers can be configured based on the URL. An example use case would be using dojo/request/xhr for same domain requests and dojo/request/script for cross domain requests.
sources:
kitsonk, core Dojo contributor
dojo/request/registry documentation
dojo/request documentation

Related

ASP.NET User Control & AJAX

I have this ASP.NET User Control that (as a part of its rendering phase) needs to execute some javascript at client-side. I use ScriptManager.RegisterStartupScript to register the script I want to execute when response reaches the client. Now, in my scenario my control is contained inside an Update panel (to be more precise, it is ajaxified using a Telerik RadAjaxManager). On the same page, I have a second Update panel (again to be more precise, a second panel ajaxified with a second RadAjaxManager setting). When this second panel raises a partial postback, I expect the changes (including any emitted script) from my control to be ignored. This is not the case and frustratingly, I cannot determine what to do? Any ideas ?
IDEA #1: Stop using UpdatePanel.
ASP Webforms are great for a lot of things...partial page rendering is not one of them. While the UpdatePanel does technically perform "partial page-rendering", it also performs a full postback.
Instead, use this alternative . . .
Create an ASP Web API and regain control over your page loading process. By creating a web API controller (which is pretty much just a function on the server that you can call using javascript) you can pass to the server specific information, run only the function (or functions) necessary for the action you are performing, and then return the exact data you need to display on your client.
The same javascript function that makes the call to the server (i.e., your ASP Web API controller) will also handle the response returned, which is easily formatted in the always-simple-to-use JSON format. In the end, your javascript would look something like this:
$('.show-kitten-button').click(function () { // this binds the click event whatever button begins the action.
// then we'll store some values in our variables
var kittenType = $('input.kitten-type').val(); // "calico" ...from asp textbox with a CssClass="kitten-type" attribute.
});
// function to make the call to the ASP Web API controller.
function getKittenPicture(kittenType) {
$.ajax({ // jQuery's AJAX function works well
type: "GET" // there are four types of requests: get, post, update, and delete. You can do most actions with get and post.
, url: 'http://yourWebSite.com/api/kittens/' + kittenType // the URL that routes to your ASP Web API controller. This is specified in the global.asax file.
, success: function (data) { // handle the data if the HTTP response indicates success
if (data || false) { // if data exists
var jsonData = JSON.parse(data); // parse it as JSON. This is assuming you are returning a serialized class object from C# or VB.NET. See below for more info on this.
var kittenImageSrcUrl = jsonData.src; // grab the data from the JSON object.
showKittenImage(kittenImageSrcUrl); // run the function to show the kitten image.
}
}
, error: function (data) { // handle the data if the HTTP response indicates an error.
console.log('An error occurred while retrieving the cute kitten picture.');
console.log('Error response: ', JSON.parse(data.responseJSON));
}
, complete: function (data) {
// any code to perform once the success (or error) function is complete.
}
});
};
function showKittenImage(imgSrc) { // function to show cute kitten image
$("#kittenImage").attr("src", "kittenImageSrcUrl"); // change the src attribute of the image to match the src URL we got back from the server.
};
More info
If you haven't yet dabbled in the world of APIs, then you're in for a real treat, because it is much, much easier and more effective than using UpdatePanels. UpdatePanels seem simple at first glance--there's not much to making one and they do give the appearance of dynamic page content--but once you start adding multiple panels, inserting start-up scripts, etc...it gets hairy very quickly. Below here are links to everything you'll need to build your first API. I encourage you to check them out...
Chad Carter's tutorial on how to implement ASP Web API in Webforms. (VB)
Microsoft's tutorial on how to use ASP Web API with Webforms. (C#)
Making POST requests to ASP Web API with multiple parameters.
Using jQuery to POST parameters from body. (VB & C#)

How to display error on the client when using ASP.NET MVC AJAX

I am using ASP.NET MVC AJAX with the #AJAX.ActionLink helper to implement item deletion from a grid. When the request is executed it returns the grid without the deleted item and the AJAX helpers replace the grid. This works just fine but the problem is what to do if the item cannot be deleted (in my case due to foreign key constraints). How can I report the error to the client and display appropriate message. I don't want to use the OnFailure function blindly because I don't want to show the same error message for all errors. Ideally there will be a way to send specific error from the action and inspect the error in the JavaScript OnFailure function but I can't seem to find it.
Of course I can downgrade to returning JSON, manually executing AJAX calls and replacing UI elements but I don't really feel like it. I'd rather do something dirty like render a hidden input with the error information and check for it on the client but I don't want to do that either if there is better way.
You can return status code and error message from the controller and pass it to the ajax OnFailure function
return new HttpStatusCodeResult(HttpStatusCode.Conflict, "The entity is currently used");
as shown here: ASP.NET MVC AJAX onError handling
and in the client side JS:
function deleteFailure(responce) {
var statusCode = responce.status;
var responceText = responce.statusText;
if(statusCode == 409){
//do something specific for specific errors
}
alert(responceText);
}

web api calls routing to wrong method

I have a webapi controller which goes against the default webapi convention to expose a few different "get" methods
[HttpGet]
[WebAPIValidateAntiForgeryTokenAttribute]
public Manufacturer[] GetManufacturers()
{
var profiler = MiniProfiler.Current;
using (profiler.Step("WCF Service Call: GetManufacturers"))
{
return IvService.GetManufacturers();
}
}
[HttpGet]
[WebAPIValidateAntiForgeryTokenAttribute]
public Range[] GetRanges(string manufacturer_code)
{
var profiler = MiniProfiler.Current;
using (profiler.Step("WCF Service Call: GetRanges"))
{
return IvService.GetRanges(manufacturerCode);
}
}
They are very simple methods which are called from Javascript and make another call out to an external system via WCF, then return the result. This has been working fine on dev for a while but recently stopped working- both calls from javascript to GetManufacturers and GetRanges now hit the same break point in GetManufacturers. I checked fiddler and its definitely calling the correct url.
Some refactoring had taken place to enforce some coding standards to do with parameter names and the call from javascript had been adjusted to from
VehicleController/GetRanges?manufacturer_code=AB
to
VehicleController/GetRanges?manufacturerCode=AB
without adjusting the corresponding webapi method. At first I had suspected this was some weird routing issue but it turns out because the parameters names no longer contained anything it recognized, it resolved to the only method which didn't required any parameters, which makes sense but kept me scratching my head for a little while!

How do I make Asp.net recognize Ext JS form submittion as an Ajax request?

It seems like by default, Asp.net does not recognize Ext JS getForm().submit() calls as an ajax request. This is causing an issue for me because I am trying to return a JsonResult instead of a view if the request was made via Ajax.
However, when the following gets called
this.getForm().submit({
url: url,
waitMsg: 'Saving Request Details',
scope: this,
success: function (form, o) {
...
},
failure: function (form, o) {
...
}
});
inside of my Asp.net MVC action that gets called, HttpContext.Request.IsAjaxRequest() is returning false.
How can I make it so Asp.Net correctly recognizes the request as an ajax request?
Yuo can alway add hidden parameter in you form what will determ that this request is via AJAX
That extension looks for a value in the header or in the request collection of key "X-Requested-With" with a matching value of "XMLHttpRequest". You would have to set the value when you make the request because it seems like extJS isn't.
Try including an X-Requested-With entry within the form results and see if that remedies it.
HTH.

How to populate a paged Dojo.Grid with data from an ASP.Net web service?

I'm trying to populate a Dojo grid with data from an ASP.Net web service. There is going to be a lot of rows, so I want to implement paging on the server side, so the web service will accept parameters "start" and "count". I've gotten pretty close, by using QueryReadStore and overriding the "fetch" function to add additional parameters (the web service requires more than just start and count).
The immediate problem I've encountered is that the web service is returning the data as XML. I believe this is because the request does not contain a Content-Type header indicating a preference for json (which the grid wants). I am using an Http-Post rather than the default Get. Is a ResponseFormat attribute supposed to override this? It doesn't work for me.
So, how do I get the data as json? Or alternately, am I barking up the wrong tree? It would seem like a pretty common thing to glue together a grid and a web service. Does Dojo have any built-in functionality for this that I am just not aware of?
Thanks
You should be able to simply set the handleAs parameter on your call to dojo.xhrPost(..) to "xml", this will bind the XML to javascript objects to make your life easier while handling the data:
dojo.xhrPost({
url: "http://whatever.com/someendpoint",
handleAs: "xml",
load: function(response, ioArgs){
/*
* Do something with response, it's a JS object that reflects the XML.
*/
}
});
Alternatively, you could chose to send different HTTP Headers in your AJAX call by using the headers property of the argument object for dojo.xhrPost(..):
dojo.xhrPost({
url: "http://whatever.com/someendpoint",
handleAs: "json",
headers: {
"Accept" : "text/javascript, text/json, application/json, application/javascript"
},
load: function(response, ioArgs){
/*
* Do something with response, it's a JS object that reflects the JSON.
*/
}
});

Resources