How to properly reuse the code when making an ajax call - javascript

I'm using the latest JQuery (3.6).There are multiple ajax call in my code to the same end point. I've to make duplicate methods because based on the response, in the .done function, I have to apply separate business logic and in case of error apply additional logic to show the error to the user. I'm wondering if I can reuse the same ajax call code because that doesn't change. Here is my JS functions:
js function 1
function dosomething1(req) {
var send_on = "/api/url";
var timeoutTime = 10000;
$.ajax({
type: "POST",
url: send_on,
contentType: 'application/json',
data: JSON.stringify(req),
cache: false,
dataType: "json",
tryCount: 0,
retryLimit: 1,
timeout: timeoutTime
})
.done(function(response) {
// this is where I'm doing my businses logic
do_very_specific1_to_response(response);
})
.fail(function(xhr, status, error) {
// this is where I'm doing error handling
handle_very_specific1_to_response();
}
js function 2
function dosomething2(req) {
var send_on = "/api/url";
var timeoutTime = 10000;
$.ajax({
type: "POST",
url: send_on,
contentType: 'application/json',
data: JSON.stringify(req),
cache: false,
dataType: "json",
tryCount: 0,
retryLimit: 1,
timeout: timeoutTime
})
.done(function(response) {
// this is where I'm doing my businses logic
do_very_specific2_to_response(response);
})
.fail(function(xhr, status, error) {
// this is where I'm doing error handling
handle_very_specific2_to_response();
}
As you can see, I am not chaning anything for ajax request and retry logic, that is always same, what changes is how I'm handling the response.
I was thinking to apply $.when().then() mechanism but not sure how it would handle the retry logic.

One approach would be to wrap the ajax call in a promise.
function dosomething(req) {
return new Promise((resolve, reject) => {
var send_on = "/api/url";
var timeoutTime = 10000;
$.ajax({
type: "POST",
url: send_on,
contentType: 'application/json',
data: JSON.stringify(req),
cache: false,
dataType: "json",
tryCount: 0,
retryLimit: 1,
timeout: timeoutTime
})
.done(function(response) {
// this is where I'm doing my businses logic
resolve(response);
})
.fail(function(xhr, status, error) {
// this is where I'm doing error handling
reject(error);
})
}
}
function dosomething1(req) {
dosomething(req)
.then(response => {
do_very_specific1_to_response(response);
})
.catch(error => {
handle_very_specific1_to_response();
})
}
function dosomething2(req) {
dosomething(req)
.then(response => {
do_very_specific2_to_response(response);
})
.catch(error => {
handle_very_specific2_to_response();
})
}

Related

Make an API call inside of another API call?

I basically need to combine data from two different API calls. Here is what I have right now:
var url= "https://website.com/api.json";
$.ajax({
url: url,
type: "GET",
dataType: 'json',
headers: {'X-API-Key': 'xxxxxx'},
success: function(data){
var api = data.results[0].api;
for (var i=0;i<api.length;++i)
var api2url = api[i].api2url;
{
$('tbody').append('<tr><td>'+api[i].thing+'</td></tr>');
}
}
});
The above works.
The problem is that I also need data from https://website.com/api2.json (which will come from data from the api1 call). I need my final code to look like:
$('tbody').append('<tr><td>+api[i].thing+'</td></tr>');
Easiest way forward would be to make that API call in the success callback of your first API call. Might look something like:
var url= "https://website.com/api.json";
$.ajax({
url: url,
type: "GET",
dataType: 'json',
headers: {'X-API-Key': 'xxxxxx'},
success: function(data){
// now you have closure over results from api call one
$.ajax({
url: 'apiURL2', // or something
type: "GET",
dataType: 'json',
headers: {'X-API-Key': data.results.apiKey // or something },
success: function(moreData){
var api = data.results[0].api;
for (var i=0;i<api.length;++i)
{
$('tbody').append('<tr><td>'+api[i].thing+ moreData.thing'</td></tr>');
}
}
})
});
const getDataFromApi = (endpoint) => {
return new Promise((resolve, reject) => {
$.ajax({
url: url,
type: "GET",
dataType: 'json',
headers: {'X-API-Key': 'xxxxxx'},
success: (data) => {
return resolve(data);
}
});
});
};
Promise.all([
return getDataFromApi('https://website.com/api.json');
]).then((data) => {
return Promise.all([
data,
getDataFromApi('https://website.com/api2.json')
]);
// here your business logic (for loop in your code)
}).then((data) => { // with bluebird it's easier use spread
const dataApi1 = data[0];
const dataApi2 = data[1];
})
.catch((err) => {
console.error(err);
});
You can make the second ajax call on the success of the first. Then perform your DOM updates as needed. But the idea is to run the second ajax call once the first has completed and was successful.
function callApi2(aip1) {
$.ajax({
//params for the call
url: api1.api2url,
success: function(data) {
var api2 = data.results[0].api; // or whatever the property is
$('tbody').append('<tr><td>'+api1.thing+'</td></tr>');
},
});
}
var url= "https://website.com/api.json";
$.ajax({
url: url,
type: "GET",
dataType: 'json',
headers: {'X-API-Key': 'xxxxxx'},
success: function(data){
var api1 = data.results[0].api;
for (var i=0; i<api1.length;++i){
callApi2(api1[i]);
}
}
});

How to use javascript promises ES6 instead of jQuery ajax call?

I was trying to understand how promises works in javascript but I didn't found clear info about this, I would like to know if it possible and it is so how to do this using promises instead this code (equivalent)
$.ajax({
type: 'post',
cache: false,
url: 'myfile.php',
data: { info: info },
datatype: 'json',
success: function(response) {
console.log(response);
}
});
I ask this because I want to use only javascript without any framework or plugins, I have no problem with the other new feautures of ES6 just with this one, I hope you can help me, thanks.
You could do it like this
function doAjax() {
return $.ajax({
type: 'post',
cache: false,
url: 'myfile.php',
data: { info: info },
datatype: 'json',
});
}
doAjax.then(function(data) {
// do success stuff
}).fail(function() {
// do fail stuff
});
You have to wrap your ajax call with a function that instantiates and returns a promise:
function getSomething() {
return new Promise((resolve, reject) => {
$.ajax({
type: 'post',
cache: false,
url: 'myfile.php',
data: { info: info },
datatype: 'json',
success: function(response) {
resolve(response);
},
error: function() {
reject("some errors");
}
});
});
}
Then you consume your promise like below:
getSomething()
.then(response => console.log(response))
.catch(err => console.log(err));

jQuery Ajax get value via function?

I have created a save(id) function that will submit ajax post request. When calling a save(id). How to get value/data from save(id) before going to next step. How to solve this?
For example:
function save(id) {
$.ajax({
type: "POST",
url: "/post/",
dataType: "json",
contentType: 'application/json',
data: JSON.stringify({
id: id,
}),
success: function (data) {
return data;
},
error: function (error) {
return data;
}
});
}
Usage:
$('.btn-create').click(function () {
var id = 123;
data = saveArea(id); //get data from ajax request or error data?
if (data) {
window.location = "/post/" + data.something
}
}
You have two options, either run the AJAX call synchronously (not recommended). Or asynchronously using callbacks
Synchronous
As #Drew_Kennedy mentions, this will freeze the page until it's finished, degrading the user experience.
function save(id) {
return $.ajax({
type: "POST",
url: "/post/",
dataType: "json",
contentType: 'application/json',
async: false,
data: JSON.stringify({
id: id,
})
}).responseText;
}
$('.btn-create').click(function () {
var id = 123;
// now this will work
data = save(id);
if (data) {
window.location = "/post/" + data.something
}
}
Asynchronous (recommended)
This will run in the background, and allow for normal user interaction on the page.
function save(id, cb, err) {
$.ajax({
type: "POST",
url: "/post/",
dataType: "json",
contentType: 'application/json',
data: JSON.stringify({
id: id,
}),
success: function (data) {
cb(data);
},
error: err // you can do the same for success/cb: "success: cb"
});
}
$('.btn-create').click(function () {
var id = 123;
save(id,
// what to do on success
function(data) {
// data is available here in the callback
if (data) {
window.location = "/post/" + data.something
}
},
// what to do on failure
function(data) {
alert(data);
}
});
}
Just make things a bit simpler.
For starters just add window.location = "/post/" + data.something to the success callback.
Like this:
function save(id) {
return $.ajax({
type: "POST",
url: "/post/",
dataType: "json",
contentType: 'application/json',
data: JSON.stringify({
id: id,
}),
success:function(data){
window.location = "/post/" + data.something
}
}).responseText;
}
Or by adding all your Ajax code within the click event.
$('.btn-create').click(function () {
var id = "123";
$.ajax({
type: "POST",
url: "/post/",
dataType: "json",
contentType: 'application/json',
data: JSON.stringify({
id: id,
}),
success: function (data) {
window.location = "/post/" + data.something
},
error: function (error) {
console.log(error)
}
});
}

Suppressing SUCCESS alert boxes?

I have three functions that called as shown below (Functions not included):
Code:
$("#btnSubmit").click(function() {
var data = JSON.stringify(getAllSourcepData());
console.log(data);
$.ajax({
url: 'closures.aspx/SaveSourceData',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
'empdata': data
}),
success: function() {
alert("Data Added Successfully");
},
error: function() {
alert("Error while inserting data");
}
});
});
$("#btnSubmit").click(function() {
var data = JSON.stringify(getAllSpouseData());
console.log(data);
$.ajax({
url: 'closures.aspx/SaveSpousData',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
'empdata': data
}),
success: function() {
alert("Data Added Successfully");
},
error: function() {
alert("Error while inserting data");
}
});
});
$("#btnSubmit").click(function() {
var data = JSON.stringify(getAllDividentData());
console.log(data);
$.ajax({
url: 'closures.aspx/SaveDividentData',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
'empdata': data
}),
success: function() {
alert("Data Added Successfully");
},
error: function() {
alert("Error while inserting data");
}
});
});
When data is submitted successfully, three alert boxes popup, each with same message: "Data Added Successfully".
This forces user to have to close three popup boxes.
Is there a way to disable the success alert boxes leaving just one? Or even all three be disabled allowing me to come up with a custom Success message?
You could also simplified your code by using Promise.all:
$("#btnSubmit").click(function() {
var allSourcepData = JSON.stringify(getAllSourcepData());
var allSpouseData = JSON.stringify(getAllSpouseData());
var allDividentData = JSON.stringify(getAllDividentData());
Promise.all([
getData('closures.aspx/SaveSourceData', allSourcepData),
getData('closures.aspx/SaveSpousData', allSpouseData),
getData('closures.aspx/SaveDividentData', allDividentData)
])
.then( alert )
.catch( alert )
});
function getData(url, data)
{
return new Promise((resolve, reject){
$.ajax({
url: url,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
'empdata': data
}),
success: () => { resolve("Data Added Successfully") },
error: () => { reject("Error while inserting data"); }
});
})
}
You need to wait until all ajax requests are complete, like in this answer
So in your case you need to create functions for all $.ajax calls like this:
function ajax1() {
var data = JSON.stringify(getAllSourcepData());
$.ajax({
url: 'closures.aspx/SaveSourceData',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
'empdata': data
}),
success: function() {
alert("Data Added Successfully");
},
error: function() {
alert("Error while inserting data");
}
});
}
// add ajax2() and ajax3() ...
And then use only one click handler like this:
$("#btnSubmit").click(function() {
$.when(ajax1(), ajax2(), ajax3()).then(function(a1, a2, a3){
// success, display message
}, function(){
// exception
});
});
You can reorder a little your code to use the deferred method to jQuery 1.5+ otherwise you can implement as this answer:
jQuery callback for multiple ajax calls
Why you want to call 3 times for button click?
Why not put them all together?
Any how you can use variable as isAlertToBeShown= false and after pushing data make it has true. finally check the variable is true or false.

How to set the some specified time to ajax call ,So that if request is taking time retrieve the data ,It should come to the FAIL Block

var ajaxRequest = new enyo.Ajax({
cacheBust: false,
contentType: 'application/json;charset=utf-8',
method: 'POST',
timeout: 8000,
async: false,
handleAs: 'json',
data: JSON.stringify({
// Data to connect to the external service.
url: url
method: 'GET',
contenttype: 'application/json;charset=utf-8',
content: 'username=l&pwd=p' + searchParams
}),
success: function (inSender, inResponse) {
},
fail: function (inSender, inResponse) {
}
ajaxRequest.go(ajaxRequest.data).response('success').error('fail');
};
lets say ,call to the webservice taking 5 to 6 seconds time or if there is slow internet connection ,How to redirect to fail block
what about manually call to fail-callback-func, something like:
var getDataFail = true;
function getData() {
setTimeOut(fileCallbackFunc, 6000);
$.ajax({
url: yourURL,
success: doneCallbck,
error: doneCallbck,
//other ajax params
});
}
function fileCallbck() {
if (getDataFail) {
//your fail logic...
console.error('get data fail');
}
}
function doneCallbck() {
getDataFail = false;
console.error('get data done');
}

Categories