This question already has answers here:
Skipping optional function parameters in JavaScript
(4 answers)
Closed 7 years ago.
Total noob question but say if created a function called sendRequest that takes in a couple of parameters for an ajax call.
The ajax request isnt that necessary, most wanted to know about the parameters.
function sendRequest($el, url, trackingUrl, actionTypeString) {
$.ajax({
method: 'POST',
url: url,
actionTrackingUrl: trackingUrl,
actionType: actionTypeString,
el: $el,
})
}
function testCase1() {
// ......... code
this.sendRequest($someEl, url, someTrackingUrl, someActionTypeString)
}
function testCase2() {
// .......code
this.sendRequest($someEl, someUrl, someActionTypeString);
}
Where in testCase2 I want to fill the 4th parameter (actionTypeString) and not 3rd parameter?
For testCase2, you would need to pass in a null parameter.
this.sendRequest($someEl, someUrl, null, someActionTypeString);
If you want to have optional parameters, the commonly-used pattern in javascript is to pass in one object containing all of the parameters, named appropriately:
function sendRequest(options) {
$.ajax({
method: 'POST',
url: options.url,
actionTrackingUrl: options.trackingUrl,
actionType: options.actionType,
el: options.$el,
})
}
function testCase1() {
// ......... code
this.sendRequest( {
$el: $someEl,
url: someUrl,
trackingUrl: someTrackingUrl,
actionType: someActionTypeString
});
}
function testCase2() {
// ......... code
this.sendRequest( {
$el: $someEl,
url: someUrl,
actionType: someActionTypeString
});
}
Parameters are assigned to named arguments in order. If you want to pass the 4th but not the 3rd argument, you need to explicitly pass null.
function testCase2() {
sendRequest($someEl, someUrl, null, someActionTypeString);
}
Additionally, I don't believe you are using this correctly - in this case it refers to the global object. You can just reference the function name.
Related
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 1 year ago.
I have the code below:
remove Dog: function(dog) {
self = this;
const updated = this.pets.filter(o => o !== dog);
$.ajax({
type: "PATCH",
url: //irrelevant,
'data': //irrelevant,
'dataType': 'json',
success: function (result) {
self = this;
this.$emit('update:pets', updated);
},
error: function (result) {
}
});
}
I am trying to have an emit command after the success of the ajax request. The ajax works fine so don't worry about that. I am just unable to do the emitting because it says that this.$emit is not a function.
Can anyone help?
this property has access to your scope level properties because it's a function and not an arrow function. So when you access the properties or method which is not in the scope of that function, it returns undefined or not a function.
To fix it, Make your success function as an arrow function of Javascript.
success: (result) => {
this.$emit('update:pets', updated);
},
Another way is to remove the self inside the success method and use the outer self.
success: function (result) {
self.$emit('update:pets', updated);
},
I have a javascript function which must get a file and pass it with another parameter:
getJsonFile = function(fileName, callback, error, data) {
var ajaxOptions = {
url: util.pathJoin([Options.server_cache_path, jsonRelativeFileName]),
type: "GET",
dataType: "json",
success: function(album) {
callback(album, data)
},
error: error
};
The getJsonFile function is called many times in for cycles throughout the application.
However, in the callback function, I sometimes find that the value of data is altered... Why does it happen? What's the solution?
As you described above, you are calling getJsonFile function from a loop (for) and most likely passing the data parameter as reference. In that scenario, you are passing a pointer to a variable which is changing in every loop iteration and by the time the success callback is invoked, data parameter has a reference to a different object from the original call.
One way to fix this kind of problems is to make copies of the parameters you received (or at least from data) OR capture the value you are interested in using a closure to capture the current data referenced value.
getJsonFile = function(fileName, callback, error, data) {
var callbackCall = (function(myData) {
return function(myAlbum) { callback(myAlbum, myData); };
})(data);
var ajaxOptions = {
url: util.pathJoin([Options.server_cache_path, jsonRelativeFileName]),
type: "GET",
dataType: "json",
success: function(album) {
callbackCall(album);
},
error: error
};
Avoiding the callbackCall variable
getJsonFile = function(fileName, callback, error, data) {
// Code omitted...
success: (function(myData) {
return function(album) { callback(album, myData); };
})(data)
// Code omitted...
}
I'm attempting to write a couple of functions using jQuery to help me test some api endpoints that I'm writing in php. I'm a novice when it comes to Javascript and jQuery and I'm having difficulty working out what I need to read up on in order to get things working that way I need it.
Here are the requirements I'm attempting to meet:
Call should be non blocking
Functions only to be fired on success and in order
I need to pass parameters along with the functions rather than just function names
Each function needs to be able to access the data variable return by success: function(data) from within the api() function
I've read the jQuery docs and believe that deferred and promises are possibly the avenue I should be pursuing but I am not able to get an example working.
Simplified versions of my two functions:
(For clarity)
// Returns data from an api request providing something hasn't gone horribly wrong
function api( api, method, endpoint, query ) {
$.ajax({
type: method,
url: '/api/' + api + '/' + endpoint,
data: query,
dataType: 'json',
success: function(data) {
// I currently have a single hardcoded function
populate( data.result, '#resource', null );
},
error: function( data ) {
// Debug
dump(data.result);
}
});
// Do some other stuff here
}
// Example call
$('body').on('click', '#bigFatButton', function() {
// I would like to specify a function (or chain of functions)
// to be fired on success along with the api() function
api('resources', 'get', 'document', {
debug: '1',
id: '7'
})
});
This is what I'd like to achieve (something nice, short and reusable):
fn1() and fn2() are fired in order and can both access the data returned by api()
api('resources', 'get', 'document', {
debug: '1',
id: '7'
}).fn1(data, 'custom', 'params').fn2(data, {other: 'params'}).alert('wooty!');
What would be the best way of achieving something similar to this? A nudge in the right direction would be very much appreciated!
Thank you.
Try adding return statement before $.ajax() , returning data from api , utilizing .then()
function api( api, method, endpoint, query ) {
// return `$.ajax()` jQuery promise to `.then()`
return $.ajax({
type: method,
url: '/api/' + api + '/' + endpoint,
data: query,
dataType: 'json',
success: function(data) {
// I currently have a single hardcoded function
populate( data.result, '#resource', null );
// return `data`
return data
},
error: function( data ) {
// Debug
dump(data.result);
}
});
// Do some other stuff here
}
// Example call
$('body').on('click', '#bigFatButton', function() {
// I would like to specify a function (or chain of functions)
// to be fired on success along with the api() function
api('resources', 'get', 'document', {
debug: '1',
id: '7'
}).then(function(data) {
$.when(fn1(data, 'custom', 'params')
, fn2(data, {other: 'params'})
.then(function() {alert('wooty!')})
})
});
Due to the asynchronous nature of AJAX you can't chain functions directly from the API function. The data would simply not be available when the chained functions are ran. However you can do it inside the success function. You will need to construct a wrapper function.
function wrapper()
{
return {
fn1 : function(data){
//execute code for fn1 here
return wrapper();
},
fn2 : function(data){
//execute code for fn2 here
return wrapper();
},
alert : window.alert.bind(window);
}
}
}
By running wrapper.fn1(data, arguments).fn2(data, arguments).alert("whoot!") inside the success function it will work the way you intended.
Everytime you call upon the wrapper function, or a function inside it it will return the full object allowing for function chaining.
A more efficient design would be to construct the functions outside the wrapper object and only reference them inside the wrapper function.
1 - I would use the methods as arguments in an anonymous function
api('resources', 'get', 'document', {
debug : true, // better to say true or false :)
id : 7, // if your id is a number use number
callback : function(data){
fn1(data);
fn2(data);
}
});
2 - Using an array, could be cool if you have a lot to run.
// in api method..
for(var i; i < cbks.lengths; i++){
cbks[i](); // execute one by one the callbacks declared.
}
api('resources', 'get', 'document', {
debug : true, // better to say true or false :)
id : 7, // if your id is a number use number
[fn1, fn2, fn3] // here are the callbacks
});
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
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))