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));
Related
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();
})
}
I have some async ajax requests
$.ajax({
url: 'first.php',
async: true,
success: function (data) {
//do stuff
}
});
$.ajax({
url: 'second.php',
async: true,
success: function (data) {
//do stuff
}
});
...
$.ajax({
url: 'nth.php',
async: true,
success: function (data) {
//do stuff
}
});
I want to run console.log() when every request is done.
I usually write this code:
$.ajax({
url: 'first.php',
async: true,
success: function (data) {
$.ajax({
url: 'second.php',
async: true,
success: function (data) {
//till the last ajax
}
});
}
});
However someone suggest Promise.all([]).
If I had to run, lets say, 4 ajax requests, which method would be the best/quickest?
Use Promise.all().
var promises = [];
promises.push(new Promise(done=>{
$.ajax({
url: 'first.php',
async: true,
success: done
});
}));
promises.push(new Promise(done=>{
$.ajax({
url: 'second.php',
async: true,
success: done
});
}));
promises.push(new Promise(done=>{
$.ajax({
url: 'nth.php',
async: true,
success: done
});
}));
Promise.all(promises).then(()=>{
console.log("All ajax completed.");
});
The official jQuery documentation states that:
The jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the Promise interface, giving them all the properties, methods, and behavior of a Promise (see Deferred object for more information).
jQuery.when():
Provides a way to execute callback functions based on zero or more Thenable objects, usually Deferred objects that represent asynchronous events.
So you can do something like:
jQuery.when(
$.ajax({
url: 'first.php',
async: true,
success: function (data) {
//do stuff
}
}),
$.ajax({
url: 'second.php',
async: true,
success: function (data) {
//do stuff
}
}),
...,
$.ajax({
url: 'nth.php',
async: true,
success: function (data) {
//do stuff
}
})
).then(function() {console.log(...);});
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.
I initiate a function after an ajax load(), but the function I intimate calls upon an additional function, which isn't working. How do I initiate ajaxstuff() after load()?
function ajaxstuff(data) {
$.ajax({
type: "POST",
url: "do-it.php",
data: {data},
success: function() {
console.log('I got this far'); // this doesn't work / isn't called
}
});
}
function doit() {
$('form').submit(function(e) {
e.preventDefault();
var formData = new FormData(this);
console.log('I got this far'); // this works
ajaxstuff(formData);
}
}
$('.popup-loader').click(function() {
$(this).append('<div class="popup"></div>');
$('.popup').load('popup.php', function() {
doit(); // this works
}
});
Check for errors in your console, also, in your AJAX add an async option. set it to FALSE ("Setting async to false means that the statement you are calling has to complete before the next statement in your function can be called"):
function ajaxstuff(data) {
$.ajax({
async: false,
type: "POST",
url: "do-it.php",
data: data,
success: function(result) {
console.log(result); //check in your console for errors
}
});
}
Syntax error in ajaxstuff function. data: {data}, , probably should be data: data,
Also when you're passing a FormData object to $.ajax, you have to specify processData: false and contentType: false
$.ajax({
type: "POST",
url: "do-it.php",
data: data,
processData: false,
contentType: false,
success: function() {
console.log('I got this far');
}
});
I'm used to writing ruby where I get data, then I manipulate it, then I display it.
In javascript land, I'm getting some json, on success: manipulate and display.
I want to separate out my code to look like this
$("#uiElement").click(function(){
data = getData();
upDateUi(data);
})
function getData(){
var fishes;
$.ajax({
url: '/api/fishes/'+q,
dataType: 'json',
success: function(data){
return data;
//I don't want to manipulate the ui in this code;
//upDateUi(data)
},
error: function(req,error){
console.log(error);
}
})
return fishes;
}
You can separate the logic that updates the UI from the logic that retrieves the data from the server using a callback pattern:
$("#uiElement").click(function(){
var upDateUi = function(data) {
/* ... logic ... */
};
getData(upDateUi);
})
function getData(callback){
$.ajax({
url: '/api/fishes/'+q,
dataType: 'json',
success: function(data){
callback(data);
},
error: function(req,error){
console.log(error);
}
})
}
For more information on functions and scopes:
https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope
For more information on how I defined the upDateUi function:
https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope#Recursion
Hard to tell what your question is, but success is any function, so this:
...
success: function(data){
upDateUi(data);
},
...
Can be equivalently written as:
...
success: upDateUi,
...
Other than that, not sure what you mean by "I don't want to manipulate the ui in this code".
Define a callback, and then in the success method invoke the callback:
$("#uiElement").click(function(){
data = getData(upDateUi);
})
function getData(callback) {
$.ajax({
url: '/api/fishes/'+q,
dataType: 'json',
success: function(data){
if (callback !== undefined) {
callback(data);
}
},
error: function(req,error){
console.log(error);
}
})
}
The only way to do that is to use a synchronous fetch, which waits for the response, but its a bad idea, as no other javascript can run (and in some browsers - nothing can run) until the response is received.
If you really, really, really want it though:
$("#uiElement").click(function(){
data = getData();
upDateUi(data);
})
function getData(){
var fishes;
$.ajax({
url: '/api/fishes/'+q,
dataType: 'json',
async: false,
success: function(data){
fishes = data;
},
error: function(req,error){
console.log(error);
}
})
return fishes;
}
I'm not shure if is this what you want.
successFunction(data){
//you can do everything here
}
errorFunction(req,error){
console.log(error);
}
function getData(){
var fishes;
$.ajax({
url: '/api/fishes/'+q,
dataType: 'json',
success: successFunction,
error: errorFunction
})
return fishes;
}
This code might be good for your needs:
var myData = $.parseJSON($.ajax({
url: "./somewhere",
type: 'get|post',
async: false,
data: { what: "ever" }
}).responseText);
Then you just proceed with whatever you want to do with the results.
$("#uiElement").click(function(){
var myData = $.parseJSON($.ajax({
url: "./somewhere",
type: 'get|post',
async: false,
data: { what: "ever" }
}).responseText);
upDateUi(myData);
})
You should probably get used to event-based programming. Your code could use callbacks:
$("#uiElement").click(function(){
getData(upDateUi); // make sure upDateUi is defined, it will be passed data
})
function getData(callback){
var fishes;
$.ajax({
url: '/api/fishes/'+q,
dataType: 'json',
success: function(data){
//I don't want to manipulate the ui in this code;
//upDateUi(data)
callback(data);
},
error: function(req,error){
console.log(error);
}
})
return fishes;
}