Creating a reusable function for deleting/confirming using callbacks - javascript

i'm not sure if this question has been asked before, i did check but i'm not sure how to actually search for it tbh.
I want to create a reusable function for deleting, confirming based on user decision. I created this simple function to edit element data with object values but i'm not able to run the callback that was set in the first function.
Or maybe it's even possible to somehow return a bool from that function based on user's decision?
Here's the logical example of what i want to achieve
function run(options, cb){
if(options['success']){
cb();
}
}
var options = {success: true};
var cbarray = new Array('id', 'token');
//calling the function and setting the callback
run(options, function(cbarray){
$.ajax({
url: 'blabla',
type: 'post',
data: {id: cbarray[0], token: cbarray[1]},
success: function(resp){
console.log(resp);
}, error: function(resp){
console.log(resp);
}
});
});
It's kinda hard to explain so i created this jsfiddle with my own code
https://jsfiddle.net/43zrqkvm/7/
Maybe i should actually use promises for that? I haven't yet had time to learn promises but maybe i should?

when you defining callback function you'r requesting argument that will be used in function body (in you'r case in ajax options) but in Run function you do not passing it
it must look like this
function run(options,arg, cb){
if(options['success']){
cb(arg);
}
}
var options = {success: true};
var cbarray = new Array('id', 'token');
//calling the function and setting the callback
run(options,cbarray, function(arg){
$.ajax({
url: 'blabla',
type: 'post',
data: {id: arg[0], token: arg[1]},
success: function(resp){
console.log(resp);
}, error: function(resp){
console.log(resp);
}
});
});

Related

Ajax test code throwing error

I am testing a code using jasmine and creating a mock object for ajax method
spyOn($,'ajax').and.callFake(function(e){
console.log("is hitting");
})
to test the following piece of code
$.ajax({
url: AppManager.defaults.contextPath + "/solutions/mcn/mcn-lookup-list",
data: {
mcnNumber : mcnNumberData,
mcnCustomerName : mcnCustomerNameData
},
dataType: "json",
type: "GET",
global: false
})
.done(function(data) {
solution.CommonObjects.theSolution.orderHandoff.mcnSearchData = self.filterMCNSearchData(data, resultObj);
$promise.resolve();
})
.fail(function() {
$promise.reject();
self.displayErrorPopup('MCN Search Error','There is no MCN associated with MCN Number or MCN Customer Name Entered!!!');
});
},
It's throwing an error cannot read done of undefined . Do I need to create a spy for that also . Please help with the code to do so
Issues with your code:
You are spying it right but you need to send in a promise object back via your spy. Basically you need to return something like this ==> return new $.Deferred().resolve(dummyData).promise();
There are multiple ways to create a deferred object/promise object. I suggest you to read both Promise & Deferred
Also could you explain where your $promise is coming from? is this some feature of require.js?
Below is one way to fake the ajax calls.
var testObj = {
ajaxFunction: function() {
$.ajax({
url: 'https://jsonplaceholder.typicode.com/posts/1'
}).done(function(data){
consoleLogFunction(data);
});
}
};
var consoleLogFunction = function(data){
console.log("The lengh of array is..=> "+ data.length);
};
describe("ajax test suite", function() {
it("expect true to be true", function() {
var dummyData = ["Foo", "Boo"];
spyOn($, 'ajax').and.callFake(function(e){
return new $.Deferred().resolve(dummyData).promise();
});
spyOn(window, 'consoleLogFunction').and.callThrough();
testObj.ajaxFunction();
expect(window.consoleLogFunction).toHaveBeenCalledWith(dummyData);
});
});

AJAX Call that Returns Javascript Variable

Struggling to return a AJAX Result Variable back to JavaScript
Note that the $.ajax call below is synchronous (async: false).
Ajax Call
function getState(callback) {
$.ajax({
url: 'getSearchState.php',
data: { "state": callback },
type: 'GET',
async: false,
success: function(result){
alert(result);
},
error: function(result) {
alert(result);
}
});
}
Ajax PHP
<?php
// Database Setup and Query
while ($row = $xxxxx->fetch(PDO::FETCH_ASSOC)) {
$StateVal = $row['State'];
}
return $StateVal;
?>
Javascript Calling the Function
var URL = District.trim();
var StateURL = getState(URL);
It gets the URL vairable from the function just fine, but doesnt return anything.
Any help would be great!
There are problems with that code both client-side and server-side.
Client-side:
Your getState is never returning anything, so it's no surprise that you don't see anything other than undefined for StateURL.
Don't use synchronous ajax. It makes for horrible UX. But if you really, really want to keep using it, here's how you would:
function getState(state) {
var result; // <=== Where we'll put our result
$.ajax({
url: 'getSearchState.php',
data: {"state": state},
type: 'GET',
async: false,
success: function(data) {
// Remember the result;
result = data;
},
error: function() {
result = /*...whatever you want to use to signal an error */;
}
});
// Return the result
return result;
}
Note that I changed the name of the argument to state, since it's not a callback.
But again, don't use synchronous ajax. Instead, use a callback or promises.
Promise: $.ajax already returns a promise, so just return that directly:
function getState(state) {
var result; // <=== Where we'll put our result
$.ajax({
url: 'getSearchState.php',
data: {"state": state},
type: 'GET',
async: false,
success: function(data) {
// Remember the result;
result = data;
},
error: function() {
result = /*...whatever you want to use to signal an error */;
}
});
// Return the result
return result;
}
Note that I changed the name of the argument to state, since it's not a callback.
But again, don't use synchronous ajax. Instead, use a callback or promises.
Promise:
function getState(state) {
return $.ajax({
url: 'getSearchState.php',
data: {"state": state},
type: 'GET'
});
}
Usage:
getState(URL)
.done(function(StateURL) {
// Use it
})
.fail(function() {
// Failed
});
Callback:
function getState(state, callback) {
$.ajax({
url: 'getSearchState.php',
data: {"state": state},
type: 'GET',
success: function(data) {
// Call the callbback with the result
callback(data);
},
error: function() {
// Call the callback with an error
callback(/*...whatever you want to use tosignal an error */);
}
});
}
Usage:
getState(URL, function(StateURL) {
// Use it, check for error
});
Server-side:
As RiggsFolly pointed out, you're returning a string from your PHP code. But that won't output it. To use it client-side, you need to output it (e.g., echo and similar). And to make it easily consumed by the JavaScript, you probably want to json_encode it to ensure that it's in a format JavaScript can understand:
echo json_encode($stateVal);
Then in your success (or done) function, use JSON.parse on it:
result = JSON.parse(data);
this is jQuery and in this case you can specify context and in success function set variables on that context.... a bit crude solution but it will works. Also take a look on arrow functions and promises from ES6, it can help you a lot and give you new perspective about whole problem.
And one main thing!! Ajax is async by default so you need somehow notify your StateURL when data will be ready (here again promise at you service)

Remake ajax function

Is there a way to make a function that converts default ajax function.
This is the ajax function i have
$.ajax({
type: "POST",
url: "http://" + document.location.host + '/userajax',
data: 'type=register&name=' + name,
beforeSend:function() {
},
success: function(response) {
}
});
This is what i want it to look like
ajax('url', {
method: 'get',
parameters: {
name: $('#name').val()
},
beforeSend: function() {
},
success: function(transport) {
}
});
Ive tried to search on the internet but did not find anything
Sure, you can create the function like this:
function ajax(url, params){
// everything is now available here
console.log( url ); // output: http://www.google.com
// you can get the data of the params object like this
console.log( params.method ); // output: get
// you can execute the beforeSend like this:
params.beforeSend();
// additionally you might want to check everything.
// maybe if the method is NOT set, you want it to always use GET
switch(arguments.length) {
case 1: url = throw new Error('Url should be set');
case 2: params.method = 'get';
case 3: break;
default: throw new Error('illegal argument count')
}
}
You would call this like:
ajax('http://www.google.com', {
method: 'get',
parameters: {
name: $('#name').val()
},
beforeSend: function() {
// some function
},
success: function(transport) {
// some function
}
});
This certainly is possible, it's just a bit of work. Some of the basics you need:
First of all, you need a good understanding of the XMLHTTPRequest API, you can find more info on that on MDN.
Next, finding out how to do a callback, that is actually quite simple, you can pass an anonymous function reference as an option or attribute for a function. That goes like this:
function doSomething(variable, callback){
variable = variable + ' something'; // just doing something with the variable
callback(variable);
}
// then call the function with a callback (anonymous function)
doSomething('doing', function(result){ alert(result); });
You should get an alert that says 'doing something'.
And finally you should know how to read an object, passed as 'options' in the ajax function. Say you have a function like this:
function foo(url, options){
console.log(url);
console.log(options.method);
console.log(options.parameters.name);
}
// call it like this
foo('https://google.com/', {
method: 'get',
parameters: {
name: 'myName'
}
});
That should log the url, method and parameters in the console.
Now from here, you should have all the pieces to put the puzzle together. Good luck!
I don't think so. but you can do this:
$(document).ready(function(){
var parameters = {
name: $("#name").val(),
desc: $("#desc").val()
};
$.ajax({
url: 'path/to/file',
data : parameters,
beforeSend: beforeSubmit,
dataType: "json",
type : 'POST',
})
.done(function(data) {
})
.fail(function() {
console.log("error");
})
})
Also note I don't set the function for the beforeSend directly in the call, I will create an externe function which gives me more freedom.
so I could do this:
function beforeSubmit(){
if(something !== 'somethingelse'){
return false; //ajax call will stop
}else{
return true; //ajax call
}
}

Declare one Ajax Function and fill it with different variables

I'm trying to make my page more efficient by using a separated ".js" file and trying to declare multilple used functions only one time. So I have to declare them in a way, that they caa be used for different situations. For Example passing different data.
Here is my Ajax Function in the "functions.js" file:
function CallAjax(type, url, data, div){
$.ajax({
type: type,
url: url,
data: data,
success: function (data) {
console.log(data);
$(div).html(data);
}
});
}
Here is my Code in my PHP File where I use this function and pass Parameters:
CallAjax('POST', 'about.php', '{ aufid : id }', '#con2');
My Problem is the "data" section. How can I declare it? The way I'm doing it doesn't work.
I don't want to use a new Ajax Function everytime when I need different data... I'm trying to trigger less functions as possible.
If you have any tips to make the page more efficient by trying to use less code, then it would be awesome if you mention them, too! Thank you!
you can do it like this:
var obj = {
aufid: 1
};
CallAjax('POST', 'about.php', obj, '#con2');
I propose js callback:
function CallAjax(type, url, data, div){
$.ajax({
type: type,
url: url,
data: data,
success: function (data) {
callback(data);
}
});
}
var obj = {
id:1
};
CallAjax('POST', 'about.php', obj, function(response){
$(div).html(response); //or other
});
or a more elegant way in promise:
function CallAjax(type, url, data){
return $.ajax({
type: type,
url: url,
data: data,
});
}
var obj = { id: 1 };
var jxhr = CallAjax('POST', 'about.php', obj);
jxhr.done(function(response){
//successful callback goes here...
}).fail(function(response){
//failure callback goes here...
}).always(function(response){
//always callback goes here...
});
: )

Triggering a Javascript callback after a completed ajax call within an object

I'm trying to trigger an action after a Javascript object has been created via an AJAX call. My object looks something like this:
function API(uid,accessToken){
$.ajax("path/to/file", {
type: "POST",
data: { user: uid, auth: accessToken },
dataType: "json",
success: function(jsonData) {
arrayname = jsonData[values]
}
});
}
I tried to use JQuery's $.when function to do a callback after the object setup is complete (ie. the array is populated with the ajax response), which looked like this:
$.when( API = new API(uid, accessToken) ).then(function() {
...success function...
});
...but the $.when function triggers with the arrayname values still undefined. From the function's standpoint the deferred object is resolved even though the object values have not yet been set. I've since tried a number of ways to make the API object become deferred based on the completing of the entire ajax call and the setting of the variables, but I'm a bit stuck on the best way to do this.
Any pointers would be most appreciated! Thanks.
You could pass the callback function when you create the object, like so:
function API(uid,accessToken, callback){
$.ajax("path/to/file", {
type: "POST",
data: { user: uid, auth: accessToken },
dataType: "json",
success: function(jsonData) {
arrayname = jsonData[values]
callback(jsonData[values])
}
});
}
and then instantiate the object like so
var api = new API(uid, accessToken, function(array) {
// success function
});
If the problem is due to the "success" callback running after the "then" callbacks, you could try turning success callback into a then callback as well. I don't use JQuery but I guess it would look something like:
function API(uid,accessToken){
return $.ajax("path/to/file", {
type: "POST",
data: { user: uid, auth: accessToken },
dataType: "json",
}).then(function(jsondata){
arrayname = jsondata[values]
});
}
$.when( API = new API(uid, accessToken) ).then(function() {
// ...
});
The reason you use $.when is when you are correlating the callbacks of multiple promises, async tasks, etc. Since jQuery 1.5, all calls to $.ajax and all the wrappers ($.get and $.post) all return promises. Therefore you don't need to wrap this call with the $.when statement unless you want to do $.when(ajaxCall1, ajaxCall2).
Since you want to filter the result from the server, you should use the pipe method of promises:
function API(uid, accessToken)
return $.post(
type: 'POST'
,data: { user: uid, auth: accessToken }
,dataType: 'json'
)
.pipe(function(json) {
return json[values];
})
;
}
This allows you to write your code the way you desire:
API(uid, token)
.then(
// success state (same as promise.done)
function(arrayname /* named from your sample script*/) {
alert('success! ' + arrayname);
}
// error state (same as promise.fail)
,function(jqXHR, status, error) {
console.warn('oh noes!', error);
}
)
.done(function() { /* done #2 */ })
.fail(function() { /* fail #2 */ })
;
Note: promise.pipe() also allows you to filter (change the data passed to) the error callback as well.

Categories