Knockout: How to put $.get into a function? - ajax

I am using getJSON in my knockout view:
$.getJSON("/GetItems", function (data) {
self.Items(data.map(viewModelFromData));
});
I want to make it a function for reuse so next time I can reload items on page action. How to do it?
When I tried:
self.getBasketItems = $.getJSON("/umbraco/Surface/Booking/GetBasketItems",
function(data) {
self.Items(data.map(viewModelFromData));
// or return data.map(viewModelFromData);
});
I got self.getBasketItems() is undefined.

The quickest fix:
self.getBasketItems = function() {
return $.getJSON(
"/umbraco/Surface/Booking/GetBasketItems",
function(data) {
self.Items(data.map(viewModelFromData));
});
};
This returns the promise, so you can use it in a chain like so:
self.getBasketItems().then(function() { console.log(self.Items()); })
You can also make a more general utility function like:
const getTransformWrite = (url, converter, target) =>
() =>
$.getJSON(url)
.then(converter)
.then(target);
}
}
self.getBasketItems = getTransformWrite(
"/umbraco/Surface/Booking/GetBasketItems",
data => data.map(viewModelFromData),
self.Items
);
I don't really think this is an improvement, but it might suit your style.
Make sure you don't forget to handle exceptions/errors!

what #haim770 suggested was this:
self.getBasketItems = function() {
return $.getJSON(
"/umbraco/Surface/Booking/GetBasketItems",
function(data) {
self.Items(data.map(viewModelFromData));
});
};
But, from your comments, it seems you're trying to actually return the value into self.getBasketItems? In that case, you will need to do a synchronous call (getJSON is asynchronous) using the $.ajax method instead.
self.getBasketItems = function() {
var _r;
$.ajax(
dataType: "json",
async: false,
url: "/umbraco/Surface/Booking/GetBasketItems",
success: function(data) {
_r = self.Items(data.map(viewModelFromData));
});
return _r
};
Please note that this second solution is very quirky. And the browser will actually hang waiting for the response from the server. You would be better of using either callbacks or promises.
Let me know if this helps!
Cheers,

Related

jQuery.getJSON equivalent in MooTools

Is there any jQuery.getJSON() equivalent in MooTools? I have a json file named data.json and I want to get its content by calling data.json file using MooTool. Is it possible? I tried Request.JSON() method but it didn't work for me. The below is my code,
var json_req = new Request.JSON({
url:'../public_html/data/data.json',
method: 'get',
secure: true,
data:{
json: true
},
onSuccess: function (res){
this.result = res;
},
onFailure: function(){
this.result = "failed";
}
}).send();
Also from the http://demos111.mootools.net/ I found an Ajax class named Ajax() which they are widely using through out their tutorial. But in MooTools documentation I didn't find this Ajax() class. I tried to use the Ajax() by replacing my Request.JSON(), but got an "Ajax not defined" error. What is this Ajax class and how can we use it in MooTools?
Here is a simple example of the functionality you are looking after. Basically wrapping a function around the Class... you could use the Class directly also.
function getJSON(url, callback) {
new Request.JSON({
url: url,
onSuccess: callback
}).send();
}
// and invoque it:
getJSON('/echo/json/', function(json) {
console.log(json);
});
you can check it live here: https://jsfiddle.net/w64vo2vm/
This one works for me
window.addEvent('domready', function() {
new Request.JSON({
url: url,
data: {'delay': 1},
method: 'post',
onSuccess: function(response) {
var myJSON = JSON.encode(response)
console.log(myJSON);
}
}).send();
})
You may see the result here
http://jsfiddle.net/chetabahana/qbx9b5pm/
I have a small function for this task. Here's the code
var configJson;
function klak_readJson(fileurl) {
var myRequest = new Request({
url: fileurl,
method: 'get',
onRequest: function(){
console.log('loading '+fileurl+'...');
},
onSuccess: function(responseText) {
console.log('received bytes '+responseText.length);
configJson=JSON.parse(myRequest.response.text);
}
});
myRequest.send();
}
Call the function to store the JSON object into configJson
klak_readJson('/js/test.json');
Hope it helps.

Ajax wait on success before next iteration in .each loop

I have an ajax call inside a .each loop wrapped in a setInterval function.
This handles updating of many divs on a dashboard with just a few lines of code on the html page.
I am worried about server lag vs client side speed. What will happen if the server has not responded with the data before the loop moves on to the next iteration?
So, my question is, can the loop be paused until the success is executed?
Ajax call:
setInterval(function() {
$(".ajax_update").each(function(){
$.ajax({
type: "POST",
dataType: "json",
url: "ajax/automated_update/confirmed_appointments.php",
data: "clinic_id=<? echo $clinic_id ?>&tomorrow=<? echo $tomorrow ?>&"+$(this).data('stored'), // serializes the form's elements.
success: function(data)
{
$(data[0]).html(data[1]);
}
});
});
}, 5000); //5 seconds*
</script>
I have looked into .ajaxComplete() but I dont see how to apply this as a solution.
I have also looked at turning the loop into something that calls itself like:
function doLoop() {
if (i >= options.length) {
return;
}
$.ajax({
success: function(data) {
i++;
doLoop();
}
});
}
But would that not interfere with .each? I dont understand how that would play nice with .each and looping based on my div class.
I just cant figure it out! Any help would be appreciated.
I was able to get .when working with the ajax call, but I dont understand how to make .when do what I need (stop the loop until the ajax call is done).
$(".ajax_update").each(function(){
$.ajax({
type: "POST",
dataType: "json",
url: "ajax/automated_update/confirmed_appointments.php",
data: "clinic_id=<? echo $clinic_id ?>&tomorrow=<? echo $tomorrow ?>&"+$(this).data('stored'), // serializes the form's elements.
success: function(data)
{
$(data[0]).html(data[1]);
}
});
$.when( $.ajax() ).done(function() {
alert("Finished it");
});
});
After thinking about your question a bit, perhaps a good solution would be to put an event in place that would trigger a new set of updates with a minimum time between your dashboard updates. This would ensure that all your updates process, that we do wait a minimum time between updates and then trigger the update cycle once again. Thus if you DO encounter any delayed ajax responses you do not try another until the previous one has all completed.
I have not fully tested this code but is should do what I describe:
//create a dashboard object to handle the update deferred
var dashboard = {
update: function (myquery) {
var dfr = $.Deferred();
$.ajax({
type: "POST",
dataType: "json",
url: "ajax/automated_update/confirmed_appointments.php",
data: "clinic_id=<? echo $clinic_id ?>&tomorrow=<? echo $tomorrow ?>&" + myquery,
success: dfr.resolve
});
return dfr.promise();
}
};
//create a simple deferred wait timer
$.wait = function (time) {
return $.Deferred(function (dfd) {
setTimeout(dfd.resolve, time);
});
};
// use map instead of your .each to better manage the deferreds
var mydeferred = $(".ajax_update").map(function (i, elem) {
return dashboard.update($(this).data('stored')).then(function (data, textStatus, jqXHR) {
$(data[0]).html(data[1]);
});
});
//where I hang my dashboardupdate event on and then trigger it
var mydiv = $('#mydiv');
var minimumDashboardUpdate = 5000;
$('#mydiv').on('dashboardupdate', function () {
$.when.apply($, mydeferred.get())
.then(function () {
$.when($.wait(minimumDashboardUpdate)).then(function () {
mydiv.trigger('dashboardupdate');
});
});
});
mydiv.trigger('dashboardupdate');

Ajax request, how to call an other function than "success" one's?

I use JQuery Ajax function :
$.ajax({
url: ...,
success: function (){
...
},
...
});
I need to execute some code just before every call of the success function (but after the response has been received).
I suppose that this success function is triggered like an event, so is there a way to make an other function call in place of success one's?
You can use the Global Ajax Event Handlers methods to do this.
Sounds like you might want to use AjaxComplete:
$(document).ajaxComplete(function(){
// do something here when ajax calls complete
});
Be warned -- this will occur for EVERY jQuery ajax call on the page...
You could also call that other function right at the biginning of done:
$.ajax({
url: ...,
done: function (){
someOtherFunction();
},
...
});
This should pretty much accomplish what you described in your question.
Is beforeSend what you are looking for:
$.ajax({
url: "...",
beforeSend: function (x) {
//do something before the the post/get
}
}).done(function (data) {
//done code
});
I succeed in calling an other function just before success one by replacing $.ajax() by a custom function like :
function mYajax(options) {
var temporaryVariable = options.success;
options.success = function () {
console.log('Custom')
if (typeof temporaryVariable === 'function')
temporaryVariable()
};
return $.ajax(options);
}
$('button').click(function () {
mYajax({
url: "/echo/json/",
data: {
foo: "bar"
},
success: function (data, textStatus, jqXHR) {
console.log('succeed action');
},
});
});

using On success function in Jquery Ajax call

I have a .js class named Widget.js
In widget.js class I am initiating a errors.ascx control class that has a JS script function "GetErrors()" defined in it.
Now, when I call GetErrors from my widgets.js class it works perfectly fine.
I have to populate a few controls in widgets.js using the output from GetErrors() function.
But the issue is that at times the GetErrors() takes a lot of time to execute and the control runs over to my widgets class. and the controls are populated without any data in them.
So the bottom line is that I need to know the exact usage of the OnSuccess function of Jquery.
this is my errors.ascx code
var WidgetInstance = function () {
this.GetErrors = function () {
$.ajax({
url: '/Management/GetLoggedOnUsersByMinutes/',
type: 'GET',
cache: false,
success: function (result) {
result = (typeof (result) == "object") ? result : $.parseJSON(result);
loggedOnUsers = result;
}
});
},.....
The code for the Widgets.js file is
function CreateWidgetInstance() {
widgetInstance = new WidgetInstance();
widgetInstance.GetErrors();
}
now I want that The control should move from
widgetInstance.GetErrors();
only when it has produced the results.
any Help???
You can use jQuery Deferreds. $.ajax() actually returns a promise. So you can do the following:
var WidgetInstance = function () {
this.GetErrors = function () {
return $.ajax({
url: '/Management/GetLoggedOnUsersByMinutes/',
type: 'GET',
cache: false
});
},.....
Then you can process the results like so...
widgetInstance.GetErrors().done(function(result){
//process the resulting data from the request here
});
Hi Simply use async:false in your AJAX call.. It will block the control till the response reaches the client end...
var WidgetInstance = function () {
this.GetErrors = function () {
$.ajax({
url: '/Management/GetLoggedOnUsersByMinutes/',
type: 'GET',
cache: false,
async: false,
success: function (result) {
result = (typeof (result) == "object") ? result : $.parseJSON(result);
loggedOnUsers = result;
}
});
},.....
I did a simple solution for this..
I just called my populating functions in the onSuccess event of the GetErrors() of my control and everything worked perfectly..

How to populate array with data returned from ajax call?

I'm making a call to an app to fetch data (routes), then looping through that data to fetch additional data about each individual route. The final data will show up in console.log without a problem, but I can't get it into an array.
$.getJSON('http://example-app/api/routes/?callback=?', function(data) {
var routes = [];
$(data).each(function(i){
routes.push(data[i]._id);
});
function getRouteData(route, callback) {
$.ajax({
url: 'http://example-app/api/routes/'+route+'?callback=?',
dataType: 'json',
success: function(data) {
callback(data);
}
});
}
var route_data = [];
$(routes).each(function(i) {
getRouteData(routes[i], function(data) {
console.log(data); // this shows me the 13 objects
route_data.push(data);
});
});
console.log(route_data); // this is empty
});
nnnnnn's right, you have to use Deferreds/promises to ensure that route_data is populated before sending it to the console.
It's not immediately obvious how to do this, with particular regard to the fact that $.when() accepts a series of discrete arguments, not an array.
Another issue is that any individual ajax failure should not scupper the whole enterprise. It is maybe less than obvious how to overcome this.
I'm not 100% certain but something along the following lines should work :
$.getJSON('http://example-app/api/routes/?callback=?', function(data) {
var route_promises = [];
var route_data = [];
function getRouteData(route) {
var dfrd = $.Deferred();
$.ajax({
url: 'http://example-app/api/routes/'+route+'?callback=?',
dataType: 'json'
}).done(function(data) {
//console.log(data); // this shows me the 13 objects
route_data.push(data);
}).fail(function() {
route_data.push("ajax error");
}).then(function() {
dfrd.resolve();
});
return dfrd.promise();//By returning a promise derived from a Deferred that is fully under our control (as opposed to the $.ajax method's jqXHR object), we can guarantee resolution even if the ajax fails. Thus any number of ajax failures will not cause the whole route_promises collection to fail.
}
$(data).each(function(i, route) {
route_promises.push( getRouteData(route) );
});
//$.when doesn't accept an array, but we should be able to use $.when.apply($, ...), where the first parameter, `$`, is arbitrary.
$.when.apply($, route_promises).done(function() {
console.log(route_data);
});
});
untested
See comments in code.

Resources