ExtJS 3.4.0 Wait for Ajax Response - ajax

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);
}

Related

Ajax GET call in a razor page not breaking inside the method in the controller

I have the following javascript using ajax:
function MoveToWeek(weekIndex) {
if (weekIndex == 1) {
var index = #Model.WeekIndex;
index = index+1;
$.ajax({
url: '#Url.Action("RenderCalendar", "Calendar")',
data: { weekIndex: index },
type: "GET",
success: function (data) {
$("#RenderCalendarArea").html(data);
}
});
}
else if (weekIndex == -1) {
var index = #Model.WeekIndex;
index = index+-1;
$.ajax({
url: '#Url.Action("RenderCalendar", "Calendar")',
data: { weekIndex: index},
type: 'GET',
success: function (data) {
$('#RenderCalendarArea').html(data);
}
});
}
}
And the following method in my controller "CalendarController":
[HttpGet]
public ActionResult RenderCalendar(int weekIndex = 0)
{
//..snip
}
I have confirmed the ajax code runs (if I put a javascript breakpoint on the $.ajax line, it'll break there). In addition the values in the ajax method do seem to be set correctly. In the debugger the javascript method has been compiled as such:
function MoveToWeek(weekIndex) {
if (weekIndex == 1) {
var index = 0;
index = index+1;
$.ajax({
url: '/Calendar/RenderCalendar',
data: { weekIndex: index },
type: "GET",
success: function (data) {
$("#RenderCalendarArea").html(data);
}
});
}
else if (weekIndex == -1) {
var index = 0;
index = index+-1;
$.ajax({
url: '/Calendar/RenderCalendar',
data: { weekIndex: index},
type: 'GET',
success: function (data) {
$('#RenderCalendarArea').html(data);
}
});
}
}
However, when this code runs, it does not break inside the method in the controller. Can anyone see why this doesn't work?
This particular partial view didn't use the layout file... which meant it didn't import the jquery lib. That's why it didn't work. Ooops.

How to return the AJAX value in extJS?

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);
}
});
}

Knockout: Cannot map computed observables after an Ajax call

I have a view model with an Ajax call to save data:
ViewModel = function (data) {
contractsAutocompleteUrl = data.ContractsAutocompleteUrl;
var self = this;
ko.mapping.fromJS(data, lineMapping, self);
self.save = function() {
self.isBeingSaved(true);
$.ajax({
url: data.SaveUrl,
type: "POST",
data: ko.toJSON(self),
contentType: "application/json",
success: function(data) {
if (data.viewModel != null) {
ko.mapping.fromJS(data.viewModel, lineMapping, self);
};
}
});
},
I have some computed variables:
self.TotalSaturdayHrs = ko.pureComputed(function() {
var result = 0;
ko.utils.arrayForEach(self.Lines(),
function(line) {
result = addNumbers(result, line.SaturdayHrs());
});
return result;
}),
self.TotalSundayHrs = ko.pureComputed(function() {
var result = 0;
ko.utils.arrayForEach(self.Lines(),
function(line) {
result = addNumbers(result, line.SundayHrs());
});
return result;
}),
.
.
.
(all the way to Friday)
And a computed GrandTotal:
self.GrandTotalHrs = ko.pureComputed(function() {
var result = addNumbers(0, self.TotalSaturdayHrs());
result = addNumbers(result, self.TotalSundayHrs());
result = addNumbers(result, self.TotalMondayHrs());
result = addNumbers(result, self.TotalTuesdayHrs());
result = addNumbers(result, self.TotalWednesdayHrs());
result = addNumbers(result, self.TotalThursdayHrs());
result = addNumbers(result, self.TotalFridayHrs());
return result;
}),
Now after the Ajax call, the computed observables TotalSaturdayHrs are no longer computed observables, they are simply properties and so my GrandTotal calculation throws an exception.
Why is that and how do I fix this?
What your .save() function should look like (I have a hunch that this will solve your issue):
ViewModel = function (data) {
var self = this,
contractsAutocompleteUrl = data.ContractsAutocompleteUrl;
self.isBeingSaved = ko.observable(false);
self.Lines = ko.observableArray();
ko.mapping.fromJS(data, lineMapping, self);
self.save = function() {
self.isBeingSaved(true);
return $.ajax({
url: data.SaveUrl,
type: "POST",
data: ko.mapping.toJSON(self), // !!!
contentType: "application/json"
}).done(function (data) {
if (!data.viewModel) return;
ko.mapping.fromJS(data.viewModel, lineMapping, self);
}).fail(function (jqXhr, status, error) {
// error handling
}).always(function () {
self.isBeingSaved(false);
});
};
}
ko.mapping.toJSON() will only turn those properties to JSON that also went into the original mapping. ko.toJSON() in the other hand converts all properties, even the calculated ones like TotalSundayHrs.
My wild guess would be that the server returns the same JSON object it had received in the POST, complete with all the ought-to-be-calculated properties like TotalSundayHrs - which then messes up the mapping in your response handler.

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")
}
}

Looping over ajax requests in a chrome extension, not working

I was trying loop over the ajax request continuously but it was doing the ajax thing only for the last loop.
while(i<3){
var query = site_url+keywords[i]+'"' ;
$.ajax({
url: query,
type: "GET",
dataType: "html"
success: function(html) {
var el = $(html).find("#tagID");
if(el.length) {
console.log("Element exists");
var cont = 1;
}
else{
console.log("Element doesnt exist");
var cont = 0;
}
}
});
console.log(cont);
i=i+1;
}
Something along those lines:
processKeyword(0);
function processKeyword(i) {
if(i < keywords.length) {
var query = site_url+keywords[i]+'"' ;
$.ajax({
url: query,
type: "GET",
dataType: "html"
success: function(html) {
var el = $(html).find("#tagID");
if(el.length) {
//found, stop processing
result(i);
} else{
//not found, process next
processKeyword(i + 1);
}
}
});
} else {
//all processed, nothing found
result(-1);
}
}
function result(i) {
//i contains keyword index if was found, -1 otherwise
}

Resources