Creating dojo javascript function with callback - javascript

I have a dojo class like this.
var widget = declare("app.util",null, {
createSecuredLayers: function () {
$.ajax.get({
url: "/Api/GetLayer",
success: function (e) {
},
error: function () {
}
});
}
});
I want to use this object with callback parameters. I mean I want to pass success and error callbacks as parameter.
var util = new app.util();
util.createSecuredLayers({
success:function(){ },
error:function(){ }
});

createSecuredLayers: function(item) {
$.ajax.get({
url: "/Api/GetLayer",
success: item.successCallback,
error: item.errorCallback
});
}
When you call the method, don't forget to pass the response in the success callback.
util.createSecuredLayers({
successCallback: function(resp) {},
errorCallback: function(err) {}
});

You can do it like this:
var widget = declare("app.util",null, {
createSecuredLayers: function (args) {
$.ajax.get({
url: "/Api/GetLayer",
success: args.success,
error: args.error
});
}
});
var util = new app.util();
util.createSecuredLayers({
success:function(){ },
error:function(){ }
});
You should also consider using Dojo's deferred

Related

Execute success ajax from method object via dynamic function

I need to run the success of ajax from a method function of object, this work when a pass to normal variable function
methodOne = function(data) {
alert(data);
};
$(document).on('click', ".clichere", function() {
var callback = function(){};
callback = methodOne;
runAjax({dispatch_ajax : "testing"}, callback );
});
function runAjax(data, succFunction) {
$.ajax({
type: "POST",
data: data,
success: succFunction,
error: function(error) {
alert(JSON.stringify(error));
},
});
}
this not work
var myapp = function() {
this.listTableOptions = function(data) {
alert(data);
};
};
$(document).on('click', ".clichere", function() {
obj = new myapp();
runAjax({dispatch_ajax : "testing"}, obj.listTableOptions() );
});
I can't not get the data in myapp object
You want to pass the function listTableOptions instead of executing it and passing the result so the following will work:
var myapp = function() {
this.listTableOptions = function(data) {
alert(data);
};
};
$(document).on('click', ".clichere", function() {
obj = new myapp();
runAjax({dispatch_ajax : "testing"}, obj.listTableOptions );
});
Notice obj.listTableOptions instead of obj.listTableOptions()

Making a callback in a chain?

Can we make a callback in a chain like this?
Widget.update(...).onUpdate(function(data){
console.log('updated');
});
current code,
var Gateway = {};
Gateway.put = function(url, data, callback) {
$.ajax({
type: "POST",
dataType: "xml",
url: url,
data: data,
async: true,
success: function (returndata,textStatus, jqXHR) {
callback(returndata);
}
});
};
var Plugin = function() {};
Plugin.prototype = {
update : function(options, callback) {
/// other stuff
Gateway.put($url, $data, function(data){
callback(data);
}
return this;
}
}
usage,
var Widget = new Plugin();
Widget.put({
button: options.button
}, function(data){
console.log('updated');
});
but ideally,
Widget.update(...).onUpdate(function(data){
console.log('updated');
});
EDIT:
at jsfiddle.
What you are trying to do will work however you need to pass your callback to update
Widget.update(yourOptions, function(data){
console.log('updated');
});
You could also return your ajax request directly and chain onto it
var Gateway = {};
Gateway.put = function(url, data) {
return $.ajax({
type: "POST",
dataType: "xml",
url: url,
data: data,
async: true
});
};
var Plugin = function() {};
Plugin.prototype = {
update : function(options) {
/// other stuff
return Gateway.put($url, $data);
}
}
var Widget = new Plugin();
Widget.update(yourOptions).done(function() {
console.log('updated');
});
I really like the callback hell coding style, but sometimes it hurts. As suggested by other users, have you already heard about promises?
The core idea behind promises is that a promise represents the result of an asynchronous operation.
As suggested in the link above - that proposed a standard for them - once polyfill'd the browser using
<script src="https://www.promisejs.org/polyfills/promise-done-6.1.0.min.js"></script>
you will be able to create new Promise's, hence to use their nice done() attribute.
You will end up with
Plugin.prototype.update = function (options) {
return new Promise(function (fullfill, reject) {
Gateway.put($url, $data, function (data) {
fullfill(data);
});
});
};
That is, Plugin.prototype.update returns a promise.
Widget.update(...).done(function(data){
console.log('updated');
});
I have not tested the code, but the spirit is that. :)
EDIT: Using promises is awesome. I simply don't like when people discover them, use them in newer parts of the codebase but finally do not refactor the rest of it.

backbone.js - listing models contained in a collection

Tried the following:
var collectionList = users.fetch();
alert(collectionList);
This returns null despite there being models in it.
Update - this worked for me:
users.fetch({
success: function() {
console.log(users.toJSON());
},
error: function() {
// something is wrong..
}
});
users.fetch({
success: function(response) {
_.each(response.models, function(model) {
//Do something with the model here
});
}
});
users.fetch().then(function () {
console.log(users.toJSON());
});
http://backbonejs.org/#Collection-fetch
Fetch is an async method, so is empty upon being called, after you specify success and error you should be able to then list your models.
users.fetch({
success: function() {
console.log(users.toJSON());
},
error: function() {
// something is wrong..
}
});
This one also can
var that = this;
users.fetch({
success: function(collection, response) {
console.log(that.collection.toJSON());
},
error: function() {
// something is wrong..
}
});

make this jQuery Ajax async=true with closure

I wrote this object and I run it into the page I have:
var dataPage = {
getData: function() {
return $.ajax({
url: '/my_url/',
data: {
product: 'some_product',
state: 'some_state'
},
type: 'POST',
async: true,
success: function (data) {
//console.log(data);
dataPage.results = data;
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Error:' + xhr.status);
alert(thrownError);
}
});
}
,returnData: function(){
var xhr = this.getData();
//console.log(xhr);
xhr.done(function() {
//console.log(xhr.responseText);
this.results = xhr.responseText;
$('#JSON').html(this.results);
});
}
}
var results = dataPage.returnData()
console.log(results)
It works perfectly as the attribute async set to false: the data is loaded into the div with id="JSON". The two console.log()s return the data and everything works fine.
Now I would like to switch to async: true but I don't know how to apply closure to make the function pass the resulting data correctly, avoiding the xhr.responseText to be undefined because of the asynchronous nature of the getData() call.
EDITED
I edited the code above, added the returnData() function, but the last console.log() still return undefined. Adding the .done() didn't solve the problem of taking out to the global scope the results if async: true...
Use the done() callback:
var jqXHR = dataPage.getData();
jqXHR.done(function(result) {
$('#JSON').html(result);
});

jQuery's AJAX call to a javascript class method

I'm a newbee about jQuery's workflow and I would like to setup a javascript class that uses an internal method to make an AJAX request. When the request returns with success, the jQuery AJAX callback should invoke a method owned by the class itself. That's the code:
function IXClock()
{
this.m_intervalID = 0;
this.startClock = function ()
{
this.m_intervalID = setInterval(this.tictac, 500);
}
this.stopClock = function ()
{
clearInterval(this.m_intervalID);
}
this.setClockTime = function(p_strTime)
{
$('#clock').html(p_strTime);
}
this.tictac = function ()
{
$.ajax
({
type: 'POST',
url: '/rap/rapClock.php',
complete: function (data)
{
this.setClockTime(data);
}
});
}
}
The class represents a clock, with an internal method (tictac) that requests "what's the time" on the server side.
After the server says the time, the jQuery's AJAX method should invoke the setClockTime method of the IXClock class. The invoke method will update the #clock div item in the html page.
The problem is that the method this.setClockTime() results unknown and the javascript return the "this.setClockTime is not a function" error.
The question is: is there a way to invoka a class method from the jQuery's AJAX callback ?
I think that the problem is that the this in your callback function is different from the this referring to IXClock. Try:
var thisClass = this ;
this.tictac = function ()
{
$.ajax
({
type: 'POST',
url: '/rap/rapClock.php',
complete: function (data)
{
thisClass.setClockTime(data);
}
});
}
Test Case (added to site which already has jQuery loaded):
function uClass () {
this.testFunction = function(input) {
alert(input) ;
}
this.ajaxFunction = function() {
var myClass = this ;
$.ajax({
type: 'POST',
url: '/',
complete: function(data) {
alert(myClass.testFunction) ;
myClass.testFunction(data) ;
this.testFunction(data) ;
}
}) ;
}
}
var k = new uClass() ;
k.ajaxFunction() ;
It happens bacause your callback function leave in global context.
You can choose 2 ways
Use .bind function to bind context to callback function http://www.robertsosinski.com/2009/04/28/binding-scope-in-javascript/
jQuery's AJAX supports transfer some data to callback function. You can write smth like this:
:
this.tictac = function () { $.ajax ({ type: 'POST', context:this, url: '/rap/rapClock.php', complete: function (data) { this.setClockTime(data); } }); }
}
this does not refer to IXClock in your ajax callback. this allways points to the current scope (have a look at this document). You need to do something like this:
this.prototype.tictac = function ()
{
var self = this;
$.ajax
({
type: 'POST',
url: '/rap/rapClock.php',
complete: function (data)
{
self.setClockTime(data);
}
});
}
You can also use jQuery's .proxy()-function for this purpose:
this.prototype.tictac = function ()
{
$.ajax
({
type: 'POST',
url: '/rap/rapClock.php',
complete: $.proxy(function (data) {
this.setClockTime(data);
}, this)
});
}
The this in the result handler is not what you expect it is. (It is not the IXClock instance)
function IXClock()
{
this.m_intervalID = 0;
}
IXClock.prototype = {
startClock: function ()
{
this.m_intervalID = setInterval(this.tictac, 500);
},
stopClock: function ()
{
clearInterval(this.m_intervalID);
},
setClockTime: function(p_strTime)
{
$('#clock').html(p_strTime);
},
tictac: function ()
{
var that = this;
$.ajax({
type: 'POST',
url: '/rap/rapClock.php',
success: function (data) { // You want success here, not complete, IMO
that.setClockTime(data);
}
});
}
}
If you ask me, that ajax call is doing evil. It does not seem to send any data, nor modify any
state on the server, but is expecting/getting/using data from the php, yet is using the POST method.
Should've been
$.get('/rap/rapClock.php', function (data) {
that.setClockTime(data);
});
One simple solution is, to keep your callback function as self = this. This will support inheritance also.
class Record{
get_data(){
self = this;
$.ajax({
type : "GET",
url : "/get_url",
dataType : "json",
contentType: "application/json; charset=utf-8",
data : {},
success : function(data){
console.log(data);
self.load_table(data);
},
});
}
static load_table(data){
console.log(data);
}

Categories