JQuery prototyping functions - javascript

I am trying to create a prototype of the ajax object.
I have created these functions:
$.extend({
ajax_prototype : function(parammeters){
instance = this;
instance.cache = false;
instance.crossDomain = false;
instance.dataType = 'json';
instance.timeout = 30000;
instance.error = default_error_function;
$.each(parammeters,function(key,value){
instance[key] = value;
});
},
set_ajax_action : function(template,action,func,def){
template[action] = func;
}
});
ajax_prototype
Is a constructor for the object.
Sets some default settings and some defined based on every need.
set_ajax_action
Sets the function to be executed on each event.
When I create an object like this:
temp1 = new $.ajax_prototype({
'type' : 'post',
'url' : 'controller.php',
});
I get this object:
Object { cache: false, crossDomain: false, dataType: "json", timeout: 30000, error: default_error_function(), type: "post", url: "controller.php", success: function () }
But after I use this:
$.set_ajax_action(temp1,'error',function(){console.log();});
The object becomes like this:
Object { cache: false, crossDomain: false, dataType: "json", timeout: 30000, error: function (), type: "post", url: "controller.php", success: function () }
Basicly their difference is the way error function is set.
Both objects work prety good.
But I would like to make the prototype to create the object with the second form.
Can someone explain me why the difference on the two objects and how to resolve my problem?
Edit 1
I can also create the second object even if I remove the error property from my prototype and call $.set_ajax_action(...) .
My problem is why there is difference to the functions presentation to console.
I know my question is trivial and that either way the result would be the same, but I wan to know how it works.
By the way, even if I set the error property like this:
instance.error = function(){ ... };
The result will be:
Object { cache: false, ifModified: false, processData: true, crossDomain: false, dataType: "json", timeout: 30000, error: .ajax_prototype/instance.error(), url: "test" }

Console is able to trace if a function can be identified somehow. For example, if it has a name or it is assigned to variable, console will show its/variable's name. If it's created inside a function, console will show it. Example:
(function testt(){
$.set_ajax_action(temp1,'error',function(){console.log();});
})()
console.log(temp1)
this code will produce error: testt/<() (firefox).
You can hide name of function, not giving your default handler a name. For example, like this:
(function(default_error_function){
$.extend({
ajax_prototype : function(parammeters){
instance = this;
...
instance.error=default_error_function
...
},
set_ajax_action : ...
});
})(function() {/* default error handler */})
Here, scope of default_error_function symbol is not global, therefore console does not show it. At the same time, handler was created outside any other function, so console only has function () to show.

Related

How can I make ajax parameters dynamic?

Here is a part of my code:
if ( external_link ) {
data = {external_link : external_link};
} else {
data = form_data;
}
$.ajax({
url: base_url + frm.attr('action'),
type: frm.attr('method'),
data: data,
cache: false,
contentType: false, // this
processData: false, // and this should be removed when external_link isn't false
success: function (imageUpload) {
All I'm trying to do is making contentType: false and processData: false parameters dynamic. I mean, if the condition above was true, then those two mentioned parameters should be removed. How can I do that?
var ajaxParams = {
url: base_url + frm.attr('action'),
data: data
// contentType not here
};
if (something) {
ajaxParams.contentType = false; // add new parameter
}
$.ajax(ajaxParams);
What about defining the minimum set of options first, and add the other two if the condition is met?
var options = {
url: base_url + frm.attr('action'),
type: frm.attr('method'),
data: data,
cache: false,
success: function (imageUpload) {
...
};
if ( external_link ) { // the external link entered
options.contentType: false; // this
options.processData: false; // and this should be removed when external_link isn't false
options.data = {external_link : external_link};
} else {
options.data = form_data;
}
$.ajax(options);
Pass an object into ajax call instead creating a literal object there? Preferably by wrapping a function around the call.
Code below is not direct implementation but showcase of principle:
var makeAjaxAndExecute = function(param1, param2){
var ajaxObjectInitiate = {object literal here}
ajaxObjectInitiate.param1 = param1;
ajaxObjectInitiate.param2 = param2;
$.ajax(ajaxObjectInitiate //.... rest of your code
}
You can further separate configuring the object and actually making the call, you can have general generator of requests elsewhere totally depends what are your needs and how complex do you wanna / need it to be.
If you need to do it on a lot of calls, I would opt for totally isolated builder that holds onto object and has getters and setters for options and possibly internal states and logic. And once object is set simple pass it to ajax call.
Scale-able, maintainable and easy to debug but not needed if you have simple logic as this.

How to set function as value to property that expects anonymous function

I'm using jquery API - jquery DataTables and I have this code snippet :
oSettings.aoDrawCallback.push({
"fn": function(){
},
"sName": "user"
});
Inside the body of the function I want to execute an Ajax request. when I write it drectly here like so:
"fn": function(){
$.ajax({
url: "url",
type: "POST",
async: false,
data: data,
success: function (data) {
console.log(data);
}
}),
There is more that is just an example to show the way everything's work fine. Then I create my own function :
function initCredits(id, inputVal, chkSelected) {
console.log(id);
$.ajax({
url: "URL",
type: "POST",
async: false,
data: data
success: function (data) {
}
})
}
and try to assing it do fn like so:
oSettings.aoDrawCallback.push({
"fn": initCredits(id, inputVal, chkSelected),
"sName": "user"
});
which gives me an error Uncaught TypeError: Cannot read property 'apply' of undefined. Now the text comes from the jquery DataTables API but there may be only two reasons I can think of that may break my code, since it's working befor taking it to outer function. First - I'm tryng to assing the function in a wrong way and second - as you may see I need three variables for my ajax request (id, inputVal, chkSelected) which are collected from the function where I'm doing this :
oSettings.aoDrawCallback.push({
"fn": initCredits(id, inputVal, chkSelected),
but the console log shows that the values are correct so I think this is less likely to be the problem, but still I consider it.
This:
"fn": initCredits(id, inputVal, chkSelected),
… calls the function and assigns the return value.
To assign the function, just do:
"fn": initCredits,

what is 'this' refers to in jquery's $.ajax success?

Sorry if I have made some mistakes of js terms in my question.
I'm trying to call a method in $.ajax success event which is within the same namespace, here is the demo:
"use strict";
var example = window.example || {};
example.Demo = {
doSomething: function(data) {
console.log(data);
},
main: function() {
$(document).ready(function() {
$.ajax({
url: 'url/to/some/place',
type: 'GET',
async: true,
dataType: "json",
success: function (data) {
this.doSomething(data);
}
});
});
},
};
example.Demo.main()
but it will fail with the following error:
Object # has no method 'doSomething',
seems this can works:
...
main: function() {
var that = this;
...
...
success: function (data) {
that.doSomething(data);
...
but I want to know whether there is any best practice for such case, or this is exactly the proper solution.
it refers the ajax settings by default, you can use the context to pass a custom object
context
This object will be made the context of all Ajax-related callbacks. By
default, the context is an object that represents the ajax settings
used in the call ($.ajaxSettings merged with the settings passed to
$.ajax).
example.Demo = {
doSomething: function (data) {
console.log(data);
},
main: function () {
//don't use dom ready handler here
$.ajax({
url: 'url/to/some/place',
type: 'GET',
//see the use of context
context: this,
async: true,
dataType: "json",
success: function (data) {
this.doSomething(data);
}
});
},
};
In JavaScript this always refers to the “owner” of the function we're executing, or rather, to the object that a function is a method of. When we define our faithful function doSomething() in a page, its owner is the page, or rather, the window object (or global object) of JavaScript. An onclick property, though, is owned by the HTML element it belongs to.
This "ownership" is the result of JavaScript's object oriented approach. See the Objects as associative arrays page for some more information.
Remove $(document).ready(function(){... inside the main , that will solve the problem

How can I pass an object in addition to json from my ajax function?

I have the following code:
function submitHandler(dialog) {
dialog.$submits.disableBt();
dialog.$message.addMessage("loading", "<li>Contacting Server, please wait ...</li>");
$.ajax({
url: href,
dataType: 'json',
type: 'POST',
data: dialog.$form.serializeArray()
})
.done(onSubmitDone())
.fail(onSubmitFail());
}
This function has a parameter of dialog which is an object looking like this:
{
$modal: $modal,
$form: $modal.find('.form'),
$message: $modal.find('.message'),
$submits: $modal.find('.submit-button'),
href: $form.attr('data-href')
};
I need to send the dialog object to the onSubmitDone and onSubmitFail functions. Previously I was not using an object
to hold $modal, $form etc and the variables were all available to all functions that were enclosed within an outer function
Two questions:
Is it sensible to pass things around as parts of an object or should I just declare these variables at the top of an outer function.
If I do pass around the object how can I pass it to the following:
function onSubmitDone(json) {
json = json || {};
if (json.Success) {
switch (action) {
I understand that my json object is passed but how can I pass the dialog object also?
One way of passing your dialog argument to the ajax callbacks is to enclose it in the callbacks definition, as showed bellow:
function submitHandler(dialog) {
dialog.$submits.disableBt();
dialog.$message.addMessage("loading", "<li>Contacting Server, please wait ...</li>");
$.ajax({
url: href,
dataType: 'json',
type: 'POST',
data: dialog.$form.serializeArray(),
success: function(data, textStatus, jqXHR) {
onSubmitDone(data, textStatus, jqXHR, dialog);
},
error: function(jqXHR, textStatus, errorThrown) {
onSubmitFail(jqXHR, textStatus, errorThrown, dialog);
}
});
}
I made explicit all callback arguments (data, textStatus, jqXHR, errorThrown), but you don't need to use all of them if you don't want to.
If you pass your object as the context option of $.ajax, it will be available as this inside onSubmitDone and onSubmitFail:
var jsonObj; // do you really need this global?
function submitHandler(dialog) {
jsonObj=dialog.$form.serializeArray();
dialog.$submits.disableBt();
dialog.$message.addMessage("loading", "<li>Contacting Server, please wait ...</li>");
$.ajax({
url: href,
dataType: 'json',
type: 'POST',
data: jsonObj ,
context: dialog
})
// Don't call the handlers from here, no ()!
.done(onSubmitDone)
.fail(onSubmitFail);
}
// Receives the data from the server
function onSubmitDone(response) {
// your object is available as 'this':
console.log(this.$modal);
}
// Different params here, but 'this' is the same
function onSubmitFail(jqXHR, textStatus) { /* ... */ }
Underscore js is a unique and really awesome library for object handling and manipulation
Since you want to pass your object is wise to declare it outside of the functions
Then you can access your object's parts and work with them in your functions' body.
Your code will look like this:
var jsonObj;
function submitHandler(dialog) {
jsonObj=dialog.$form.serializeArray();
dialog.$submits.disableBt();
dialog.$message.addMessage("loading", "<li>Contacting Server, please wait ...</li>");
$.ajax({
url: href,
dataType: 'json',
type: 'POST',
data:jsonObj
})
.done(onSubmitDone(jsonObj))
.fail(onSubmitFail(jsonObj));
}
Regarding your question if it is sensible to pass the object around, while you can, you might find it gets a little burdensome to do so, needing to lug the variable around whenever you need to use it. I would recommended encapsulating your dialog object in the parent scope of your submitHandler() function so it is available to submitHandler, onSubmitDone, etc.
Regarding your second question if you were to pass it around and how you'd get the dialog object to your onSubmitDone function as well, you can always pass the response and your dialog object to your onSubmitDone function like so:
.done(onSubmitDone(response, dialog))

JS: + variable is this right?

$.ajax({
type: "POST",
url: "misc/AddFriend.php",
data: {
mode: 'ajax',
friend: c,
uID: $('#uID').val(),
fID: $('#fID').val(),
bID: $('#bID').val()
},
success: function (msg) {
alert('OK');
$('#friend' + fID).slideUp('slow');
}
});
IS this right? It wont slide up right now
Well, you can find out the ID by alerting the result of the concatenated expression.
Since you're feeding an anon object you don't have a reference. It's probably easiest if you just invoke .val() again:
$('#friend' + $('#FID').val() ).slideUp('slow');
Otherwise it's probably doing $('#friendundefined').slideUp.
try:
$.ajax({
type: "POST",
url: "misc/AddFriend.php",
data: {
mode: 'ajax',
friend: c,
uID: $('#uID').val(),
fID: $('#fID').val(),
bID: $('#bID').val()
},
success: function (msg) {
alert('OK');
$('#friend' + $('#fID').val()).slideUp('slow');
}
});
The syntax is correct, but whether those ids and the value of variable c make sense in the context of your application is a different story.
I notice that you are using fID in the function to execute when the call succeeds. fID and also c would need to be defined outside of the function - I mean that you can't use the value of property fID of the object assigned to data.
You could create that object outside of the ajax function however and use the property for both data and in the selector in the function to run when the call succeeds.

Categories

Resources