How to return the AJAX value in extJS? - ajax

I am calling AJAX request and getting the value as well as a response but I want to return the value and store in a variable. I tried so many ways but its not working. PFB the code snippet.
submitRequest: function(type, url) {
var maxValue = this.getMaxValue(PORTALURL.EXCEPTION.MAX_VALUE);
if(grid.getSelectionModel().getSelection().length > maxValue){
Ext.Msg.alert('Alert!', type + ' count is more than 10');
return;
}
},
getMaxValue : function(url){
Ext.Ajax.request({
url: url,
success: function(response) {
var result = Ext.decode(response.responseText);
//callback(result); Not working
// return result; Not Working
}
});
}
How I can get the value in var maxValue ?
Appreciate all your help.

Starting from Ext JS 6 you may also use promises with Ext.Ajax.request() out of the box which may help you to organise your code in a more 'straightforward' way and get rid of a so-called 'callback hell'.
submitRequest: function(type, url) {
this.getMaxValue(PORTALURL.EXCEPTION.MAX_VALUE).then(function(response) {
var maxValue = Ext.decode(response.responseText);
if (grid.getSelectionModel().getSelection().length > maxValue){
Ext.Msg.alert('Alert!', type + ' count is more than 10');
return;
}
}).done();
},
getMaxValue : function(url) {
return Ext.Ajax.request({
url: url,
...
})
}
For the further reading I would recommend you the following article https://www.sencha.com/blog/asynchronous-javascript-promises/

As an Ajax request is asynchrone you can use a callback:
submitRequest: function(type, url) {
this.getMaxValue(PORTALURL.EXCEPTION.MAX_VALUE, function(maxValue){ // <<== Your callback
if(grid.getSelectionModel().getSelection().length > maxValue){
Ext.Msg.alert('Alert!', type + ' count is more than 10');
return;
}
});
},
getMaxValue : function(url, callback){
Ext.Ajax.request({
url: url,
success: function(response) {
var result = Ext.decode(response.responseText);
callback(result);
}
});
}

Related

Is there a way to show "Loading data.." option in Rally Grid(ext JS) while making the Ajax request to load the data?

I am trying to set the message to "Data Loading.." whenever the data is loading in the grid. It is working fine if I don't make an Ajax call. But, when I try to make Ajax Request, It is not showing up the message "Loading data..", when it is taking time to load the data. Can someone please try to help me with this.. Thanks in Advance.
_loadData: function(x){
var that = this;
if(this.project!=undefined) {
this.setLoading("Loading data..");
this.projectObjectID = this.project.value.split("/project/");
var that = this;
this._ajaxCall().then( function(content) {
console.log("assigned then:",content,this.pendingProjects, content.data);
that._createGrid(content);
})
}
},
_ajaxCall: function(){
var deferred = Ext.create('Deft.Deferred');
console.log("the project object ID is:",this.projectObjectID[1]);
var that = this;
console.log("User Reference:",that.userref,this.curLen);
var userObjID = that.userref.split("/user/");
Ext.Ajax.request({
url: 'https://rally1.rallydev.com/slm/webservice/v2.0/project/'+this.projectObjectID[1]+'/projectusers?fetch=true&start=1&pagesize=2000',
method: 'GET',
async: false,
headers:
{
'Content-Type': 'application/json'
},
success: function (response) {
console.log("entered the response:",response);
var jsonData = Ext.decode(response.responseText);
console.log("jsonData:",jsonData);
var blankdata = '';
var resultMessage = jsonData.QueryResult.Results;
console.log("entered the response:",resultMessage.length);
this.CurrentLength = resultMessage.length;
this.testCaseStore = Ext.create('Rally.data.custom.Store', {
data:resultMessage
});
this.pendingProjects = resultMessage.length
console.log("this testcase store:",resultMessage);
_.each(resultMessage, function (data) {
var objID = data.ObjectID;
var column1 = data.Permission;
console.log("this result message:",column1);
if(userObjID[1]==objID) {
console.log("obj id 1 is:",objID);
console.log("User Reference 2:",userObjID[1]);
if (data.Permission != 'Editor') {
deferred.resolve(this.testCaseStore);
}else{
this.testCaseStore = Ext.create('Rally.data.custom.Store', {
data:blankdata
});
deferred.resolve(this.testCaseStore);
}
}
},this)
},
failure: function (response) {
deferred.reject(response.status);
Ext.Msg.alert('Status', 'Request Failed.');
}
});
return deferred;
},
The main issue comes from your Ajax request which is using
async:false
This is blocking the javascript (unique) thread.
Consider removing it if possible. Note that there is no guarantee XMLHttpRequest synchronous requests will be supported in the future.
You'll also have to add in your success and failure callbacks:
that.setLoading(false);

ExtJS 3.4.0 Wait for Ajax Response

I need to assign the response value for return it in a Javascript function using ExtJS 3.4.0 library, the function naturally terminates without waiting for ajax response so the value of count is always zero, I need to know if I can do it this way or if there is an alternative.
Thanks
function test() {
var count = 0;
Ext.Ajax.request({
url: "/Controller/Action",
method: "POST",
success: function(response) {
count = Ext.decode(response.responseText);
}
});
if (count > 1) {
return false;
}
return true;
}
You need to add return statement in you success function :
function test() {
var count = 0;
Ext.Ajax.request({
url: "/Controller/Action",
method: "POST",
success: function(response) {
count = Ext.decode(response.responseText);
if (count > 1) {
this.other(false);
}
this.other(true);
},
scope: this
});
},
function other(param){
console.log(param);
}

jQuery.ajax() inside a loop [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 6 years ago.
If I call jQuery.ajax() inside a loop, would it cause the call in current iteration overwrite the last call or a new XHR object is assigned for the new request?
I have a loop that do this, while from console log I can see requests done 200 ok but just the result data of the last request in the loop is stored by the request success callback as supposed .
the code:
var Ajax = {
pages: {},
current_request: null,
prefetch: function () {
currentPath = location.pathname.substr(1);
if(this.pages[currentPath])
{
var current = this.pages[currentPath];
delete this.pages[currentPath];
current['name']=currentPath;
current['title']=$("title").text().replace(' - '.SITE_NAME, '');
current['meta_description']=$("meta[name=description]").attr('content');
current['meta_keywords']=$("meta[name=keywords]").attr('content');
}
var _Ajax = this;
//the loop in question *****
for(var key in this.pages)
{
$.ajax({
method: 'get',
url:'http://'+location.hostname+'/'+key,
success: function(data) {
_Ajax.pages[key] = data;
}
});
console.debug(this.pages);
}
if(current)
{
this.pages[currentPath] = current;
}
}
};//Ajax Obj
for(var i in pages)
{
Ajax.pages[pages[i]]={};
}
$(function() {
Ajax.prefetch();
});//doc ready
You'll need a closure for key:
for(var k in this.pages){
(function(key){
$.ajax({
method: 'get',
url:'http://'+location.hostname+'/'+key,
success: function(data) {
_Ajax.pages[key] = data;
}
});
console.debug(this.pages);
})(k);
}
that way you make sure that key is always the correct on in each ajax success callback.
but other than that it should work
i made a small closure demonstration using timeout instead of ajax but the principle is the same:
http://jsfiddle.net/KS6q5/
You need to use async:false in you ajax request. It will send the ajax request synchronously waiting for the previous request to finish and then sending the next request.
$.ajax({
type: 'POST',
url: 'http://stackoverflow.com',
data: data,
async: false,
success: function(data) {
//do something
},
error: function(jqXHR) {
//do something
}
});
I believe what's happening here has to do with closure. In this loop:
for(var key in this.pages)
{
$.ajax({
method: 'get',
url:'http://'+location.hostname+'/'+key,
success: function(data) {
_Ajax.pages[key] = data;
}
});
console.debug(this.pages);
}
The variable key is actually defined outside the for loop. So by the time you get to the callbacks, the value has probably changed. Try something like this instead:
http://jsfiddle.net/VHWvs/
var pages = ["a", "b", "c"];
for (var key in pages) {
console.log('before: ' + key);
(function (thisKey) {
setTimeout(function () {
console.log('after: ' + thisKey);
}, 1000);
})(key);
}
I was facing the same situation, I solved using the ajax call inside a new function then invoke the function into the loop.
It would looks like:
function a(){
for(var key in this.pages)
{
var paramsOut [] = ...
myAjaxCall(key,paramsOut);
.......
}
}
function myAjaxCall(paramsIn,paramsOut)
{
$.ajax({
method: 'get',
url:'http://'+location.hostname+'/'+paramsIn[0],
success: function(data) {
paramsOut[key] = data;
}
});
}
This is how I always do a ajax loop..
I use a recursive function that gets called after the xhr.readyState == 4
i = 0
process()
function process() {
if (i < 10) {
url = "http://some.." + i
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
alert(xhr.responseText)
i++
process()
}
}
xhr.send();
} else {
alert("done")
}
}

jquery $.ajax call for MVC actionresult which returns JSON triggers .error block

I have the following $.ajax post call. It would go through the action being called but then it would trigger the "error" block of the function even before the actionresult finishes. Also, it seems to reload the whole page after every pass.
var pnameVal = '<%: this.ModelCodeValueHelper().ModelCode%>';
var eidVal = '<%: ViewBag.EventId %>';
var dataV = $('input[ name = "__RequestVerificationToken"]').val();
var urlVal = '<%: Url.Action("New") %>';
alert('url > ' + urlVal);
alert('pname - ' + pnameVal + ' eid - ' + eidVal + ' dataV = ' + dataV);
$.ajax({
url: urlVal,
//dataType: "JSONP",
//contentType: "application/json; charset=utf-8",
type: "POST",
async: true,
data: { __RequestVerificationToken: dataV, pname: pnameVal, eId: eidVal },
success: function (data) {
alert('successssesss');
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest);
alert(textStatus);
alert(errorThrown);
alert('dammit');
}
})
.done(function (result) {
if (result.Success) {
alert(result.Message);
}
else if (result.Message) {
alert(' alert' + result.Message);
}
alert('done final');
//$('#search-btn').text('SEARCH');
waitOff();
});
This is the action
[HttpPost]
public ActionResult New(string pname, int eid)
{
var response = new ChangeResults { }; // this is a viewmodel class
Mat newMat = new Mat { "some stuff properties" };
Event eve = context.Events.FirstOrDefault(e => e.Id == eid);
List<Mat> mats = new List<Mat>();
try
{
eve.Mats.Add(newMat);
icdb.SaveChanges();
mats = icdb.Mats.Where(m => m.EventId == eid).ToList();
response.Success = true;
response.Message = "YES! Success!";
response.Content = mats; // this is an object type
}
catch (Exception ex)
{
response.Success = false;
response.Message = ex.Message;
response.Content = ex.Message; // this is an object type
}
return Json(response);
}
Btw, on fiddler the raw data would return the following message:
{"Success":true,"Message":"Added new Mat.","Content":[]}
And then it would reload the whole page again. I want to do an ajax call to just show added mats without having to load the whole thing. But it's not happening atm.
Thoughts?
You probably need to add e.preventDefault() in your handler, at the beginning (I am guessing that this ajax call is made on click, which is handled somewhere, that is the handler I am talking about).

Kill an ajax process

GET_DATA()
GET_DATA() contains this:
var xhr;
...
function get_data( phrase ) {
xhr = function get_data( phrase ) {
$.ajax({
type: 'POST',
url: 'http://intranet/webservice.asmx/GetData',
data: '{phrase: "' + phrase + '"}',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function( results ) {
$("#div1").empty();
if( results.d[0] ) {
$.each( results.d, function( index, data ) {
$("#div1").append( data.Group + ':' + data.Count + '<br />' );
});
} else {
alert( "results.d does not exist..." );
}
},
error: function(xhr, status, error) {
$('#spanLoading').empty();
var err = eval("(" + xhr.responseText + ")");
alert(err.Message) ;
}
});
}
function get_default() {
$('#div1').empty().append("default stuff goes here");
}
UPDATE 2 CODE
I've also tried this, which doesn't work either, no error messages, just returns the results of when the textbox had 2 characters when it finishes processing even if I delete everything before the process has finished:
$('#TextBox1').keyup( function() {
if(xhr && xhr.readystate != 4){
xhr.abort();
}
if ($("#TextBox1").val().length >= 2) {
get_data( $("#TextBox1").val() );
} else {
get_default();
}
});
UPDATE 1 CODE:
$('#TextBox1').keyup( function() {
if ($("#TextBox1").val().length >= 2) {
get_data( $("#TextBox1").val() );
} else {
if(xhr)
{
xhr.abort();
}
get_default();
}
});
ORIGINAL QUESTION:
I have the following code:
$('#TextBox1').keyup( function() {
if ($("#TextBox1").val().length >= 2) {
get_data( $("#TextBox1").val() );
} else {
get_default();
}
});
This has a slight glitch where if I type something really fast and then I delete it equaly fast, I see the data from get_default() flash on the screen, then it gets replaced by a previous ajax request where the value in the textbox was 2 which had not finished processing.
So basically, what I think is happening is that when the textbox has 2 characters in it, the ajax request starts which takes a second or 2. While this is happening, if I delete the 2 characters, I see the get_default() being successful, but it seems to replace it with the ajax data when the ajax data finishes.
How do I stop this from happening?
Thank you for posting get_data.
The reason why your AJAX call is not getting aborted is that xhr is not defined in the appropriate (window) scope; therefor, xhr.abort() doesn't do anything (and quite probably throws an error if you take a look at your console).
Please try the following:
var xhr = false;
function get_data( phrase ) {
xhr = $.ajax({ /* ... etc */
}
The rest should work as is.
Place a time delay before you execute your ajax request.
function pausecomp(ms) {
ms += new Date().getTime();
while (new Date() < ms){}
}

Resources