Cannot GET after async AJAX request in reactjs react.Component - javascript

I have a problem with my reactjs code. I've read the thread about the async world and the problems that can occur and I think I fix that, but now I get a blank with a text of Cannot GET /thenameofthepage.
This is my code right after the react.Component
getList() {
var returnValue;
$.ajax({
type: "get",
url: "###URL###",
cache: false,
async: false,
success : function(data) {
returnValue = data;
}
});
return returnValue;
}
and this is the code right after render() {
console.log(this.getList());
If I console log in the function then everything is okay. But when I try to pass it to a variable everything breaks. I did async. Not working. I tried with initial states and ComponentDidMount() again not working.
P.S
I tried by using internet guide:
constructor() {
this.state = { data: [] };
}
getList() {
$.ajax({
type: "get",
url: "http://havvamustafa.devel.signature.eu.com/manage/collection/list_all_ajax",
cache: false,
dataType: 'json',
success: (data) => {
this.setState({data: data});
}
});
}
Then
componentDidMount() {
this.getList();
}
And in the end
console.log(this.state.data);
Now it gives me error because of the constructor.

From Jquery $.ajax's documentation, the use of async: false is deprecated
async (default: true)
Type: Boolean
By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active. As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done() or the deprecated jqXHR.success().
I don't know what kind of problems do you think of when dealing with asynchronous data fetch, but don't forget that using synchronous requests freeze the browser while the request is pending. You could make it easier by doing :
getList() {
$.ajax({
type: "get",
url: "###URL###",
cache: false
}).done(this.handleSuccess);
},
handleSuccess(results) {
this.setState({data: results});
}
Your data processing is done in an other method, it will be cleaner !

Related

Wait until all Ajax finish processing inside another Ajax, then send data

I'm trying to send data off with data from multiple other Ajax requests. The issues comes when sendDataOffAjax() is called, no actual data was sent, because it fires off before any of the other functions have a change to add data. I could easily fix this by just using asyn: false everywhere, but from what I read, that's bad practice.
Here is my code:
let requests = [];
$.ajax({
url: someUrl,
method: 'GET',
dataType: 'json',
complete: function (data) {
if (data.exists) {
if (condition) {
requests.push(anotherAjax());
}
if (condition) {
requests.push(someDifferentAjax());
}
}
requests.push(alwaysRunAjax());
}
}).done(function () {
$.when.apply($, requests).done(function () {
sendDataOffAjax();
});
});
Heres what anotherAjax() looks like (All the other Ajax requests also look like this):
function anotherAjax() {
return $.ajax({
url: someUrl,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: 'GET',
dataType: 'json',
complete: function (data) {
if (data.exists) {
toSendData.data['NEW_DATA'] = {
'data': data.responseJSON
}
}
//send complete signal?
}
})
}
How could I make it wait until all the data is added through the other Ajax requests, then launch sendDataOffAjax().
The log looks like this:
Data sent
anotherAjax Data added
alwaysRunAjax Data added
someDifferentAjax Data added
When it comes to ajax requests, .complete(), according to jQuery's docs, runs only after the success or error callback is run and .done() is the same as calling .success(). So with this in mind you can see why the code in your done callback is running first. You should be able to switch the code from your complete callback to your done callback and vice-versa to get the desired effect.
So Try:
let requests = [];
$.ajax({
url: someUrl,
method: 'GET',
dataType: 'json',
complete: function () {
$.when.apply($, requests).done(function () {
sendDataOffAjax();
});
}
}).done(function (data) {
if (data) {
if (condition) {
requests.push(anotherAjax());
}
if (condition) {
requests.push(someDifferentAjax());
}
}
requests.push(alwaysRunAjax());
});
Now, as long as all of your ajax functions you are calling here return deferred objects your requests array should be filled and $.when() should wait until all the deferred objects resolve.
No this isn't possible without async:false.
The reason it doesn't count as a good thing to use is becuase it is against the idea of a Ajax which is Asynchronous.
async:false baisiclly "lock" your application to the user until your request is done and when you put it on too much ajax calls in the same time it will make your apllication seems very very slow.
In your case you it will be fine if you'll use async:false on the 2 functions as long as they don't take long to execute.

What's a non-deprecated way of doing a synchronous ajax call using jQuery?

I've got a small javascript function that's only purpose is to call a script to get some data from the database so it can be used by other functions on the client side.
I'm using a jQuery call to get the data but for me to pass the object out of the success functions scope I need to turn asynchronous off which raises a deprecation warning.
My function works as intended currently but I'd like to use a method that isn't deprecated. Here is my function:
function getData(ID) {
var Data = {};
$.ajax({
url: 'script',
method: 'POST',
dataType: 'json',
async: false,
data: {action: 'get', id: ID },
success: function(response) {
Data = response;
})
});
return Data;
}
I've changed the variable names for privacy reasons so apologies if they're vague.
Also why is synchronous calls considered harmful to the end users experience?
As AJAX call is asynchronous, you will always get blank object ({}) in response.
There are 2 approach.
You can do async:false
To get response returned in AJAX call try like below code. Which wait for response from server.
function getData(ID) {
return $.ajax({
url: 'script',
method: 'POST',
dataType: 'json',
//async: true, //default async call
data: {action: 'get', id: ID },
success: function(response) {
//Data = response;
})
});
}
$.when(getData(YOUR_ID)).done(function(response){
//access response data here
});

Running a function before async ajax request

I'm trying to run a function before async ajax request. However function is running after async request gets the respond.
Is there any way to solve this issue?
block();
ajaxRequest= $.ajax({
url: siteURL+'includes/ajax/action.php',
type: "POST",
async: false,
data: {productID : productID},
dataType: "json"
});
ajaxRequest.done(function(data) {
block(true);
if (data === false) {
alerts('error title','error info here', 'error', 200);
return false;
}
});
ajaxRequest.fail(function(jqXHR, textStatus) {block(true); alerts('error title','error info','error');});
confirm();
I run more functions after these codes. However as I stated before, block(); function is waiting till async ajax request is getting response.
If I don't run asynchronous, then I get block() and confirm() functions running at the same time so return false; losing all the meaning.
P.S. I run these codes when a form is submitted so if async request is failed I don't want it to run any other code after it. However when it is asynchronously running block() is waiting till response is returned.
Your problem is async:false. Your request is NOT an async request, it is a sync request. It blocks javascript code and browser rendering from happening while the request is being processed. With your current setup, there should be no harm in removing async: false, thus making it async.
block();
ajaxRequest= $.ajax({
url: siteURL+'includes/ajax/action.php',
type: "POST",
data: {productID : productID},
dataType: "json"
});
ajaxRequest.done(function(data) {
block(true);
if (data === false) {
alerts('error title','error info here', 'error', 200);
return false;
}
});
ajaxRequest.fail(function(jqXHR, textStatus) {block(true); alerts('error title','error info','error');});
ajaxRequest.always(confirm);

Is there any way to wait for AJAX response and halt execution?

Here is some code I'd like to execute. I'd like to wait for AJAX response so I can return something from the server. Any way to achieve this?
function functABC(){
$.ajax({
url: 'myPage.php',
data: {id: id},
success: function(data) {
return data;
}
});
//Wait for AJAX (???)
}
var response = functABC();
When using promises they can be used in a promise chain.
async=false will be deprecated so using promises is your best option.
function functABC() {
return new Promise(function(resolve, reject) {
$.ajax({
url: 'myPage.php',
data: {id: id},
success: function(data) {
resolve(data) // Resolve promise and go to then()
},
error: function(err) {
reject(err) // Reject the promise and go to catch()
}
});
});
}
functABC().then(function(data) {
// Run this when your request was successful
console.log(data)
}).catch(function(err) {
// Run this when promise was rejected via reject()
console.log(err)
})
New, using jquery's promise implementation:
function functABC(){
// returns a promise that can be used later.
return $.ajax({
url: 'myPage.php',
data: {id: id}
});
}
functABC().then( response =>
console.log(response);
);
Nice read e.g. here.
This is not "synchronous" really, but I think it achieves what the OP intends.
Old, (jquery's async option has since been deprecated):
All Ajax calls can be done either asynchronously (with a callback function, this would be the function specified after the 'success' key) or synchronously - effectively blocking and waiting for the servers answer.
To get a synchronous execution you have to specify
async: false
like described here
Note, however, that in most cases asynchronous execution (via callback on success) is just fine.
The simple answer is to turn off async. But that's the wrong thing to do. The correct answer is to re-think how you write the rest of your code.
Instead of writing this:
function functABC(){
$.ajax({
url: 'myPage.php',
data: {id: id},
success: function(data) {
return data;
}
});
}
function foo () {
var response = functABC();
some_result = bar(response);
// and other stuff and
return some_result;
}
You should write it like this:
function functABC(callback){
$.ajax({
url: 'myPage.php',
data: {id: id},
success: callback
});
}
function foo (callback) {
functABC(function(data){
var response = data;
some_result = bar(response);
// and other stuff and
callback(some_result);
})
}
That is, instead of returning result, pass in code of what needs to be done as callbacks. As I've shown, callbacks can be nested to as many levels as you have function calls.
A quick explanation of why I say it's wrong to turn off async:
Turning off async will freeze the browser while waiting for the ajax call. The user cannot click on anything, cannot scroll and in the worst case, if the user is low on memory, sometimes when the user drags the window off the screen and drags it in again he will see empty spaces because the browser is frozen and cannot redraw. For single threaded browsers like IE7 it's even worse: all websites freeze! Users who experience this may think you site is buggy. If you really don't want to do it asynchronously then just do your processing in the back end and refresh the whole page. It would at least feel not buggy.
nowadays I prefer using async function and await syntax
async function functABC(){
await $.ajax({
url: 'myPage.php',
data: {id: id},
success: function(data) {
return data;
}
});
//Wait for AJAX
}
Try this code. it worked for me.
function getInvoiceID(url, invoiceId) {
return $.ajax({
type: 'POST',
url: url,
data: { invoiceId: invoiceId },
async: false,
});
}
function isInvoiceIdExists(url, invoiceId) {
$.when(getInvoiceID(url, invoiceId)).done(function (data) {
if (!data) {
}
});
}
async: true
When we request for some data to a server, then server will may take some time to return a response. Now During this time browser interpreter resume execution it will not wait for response and continues it's execution. So that response may print second and other code output will be print first. This happens due to async is set to true. Now question arise that what this parameter does. async means asynchronously. This attribute tells to interpreter that do not does execution sequentially.
async: false
Means forcing that complete execution of this call/code first and then go for next. So it is depends on your requirement that how you use this attribute.
Example with async:
function ayncfunction() {
$.ajax({
url: 'abc.php',
data: {id: id},
async: true,
success: function(repsonse) {
return repsonse;
}
});
}
Example without async
function ayncfunction(){
$.ajax({
url: 'abc.php',
data: {
id: id
},
async: false,
success: function(repsonse) {
return repsonse;
}
});
}
use async:false attribute along with url and data. this will help to execute ajax call immediately and u can fetch and use data from server.
function functABC(){
$.ajax({
url: 'myPage.php',
data: {id: id},
async:false
success: function(data) {
return data;
}
});
}
Method 1:
function functABC(){
$.ajax({
url: 'myPage.php',
data: {id: id},
success: function(data) {
return data;
},
complete: function(){
// do the job here
}
});
}
var response = functABC();
Method 2
function functABC(){
$.ajax({
url: 'myPage.php',
data: {id: id},
async: false,
success: function(data) {
return data;
}
});
// do the job here
}

ajax call doesnt return the data from external JS file

I am trying to implement Repository pattern in JavaScript. I have ViewModel which i want to initialize with the data when i call Initialize method on it. Everything seems to be falling in places except that i am not able to return the data from my AJAX call. I can see that data is coming back from the ajax call but when i trying to capture the data in SomeViewModel's done function, it is null.
Can someone please point me out where i am going wrong here?
P.S: Please notice that i am not making Async call so the call chain is properly maintained.
This is how my Repository looks like:
function SomeRepository(){
this.LoadSomeData = function loadData()
{
$.ajax({
type: "POST",
url: "someUrl",
cache: true,
async: false,
contentType: "application/json; charset=utf-8",
data: "{}",
dataType: "json",
//success: handleHtml,
success: function(data) {
alert('data received');
return data;
},
error: ajaxFailed
});
function ajaxFailed(xmlRequest) {
alert(xmlRequest.status + ' \n\r ' +
xmlRequest.statusText + '\n\r' +
xmlRequest.responseText);
}
}
};
This is how my ViewModel looks like:
function SomeViewModel(repository){
var self = this;
var def = $.Deferred();
this.initialize = function () {
var def = $.Deferred();
$.when(repository.LoadSomeData())
.done(function (data) {
def.resolve();
});
return def;
};
}
This is how i am calling from an aspx page:
var viewModel = new SomeViewModel(new SomeRepository());
viewModel.initialize().done(alert('viewmodel initialized'));
alert(viewModel.someProperty);
I have used successfully an auxiliar variable to put the ajax result, when ajax call is inside a function (only works if ajax is async=false) and i need the function does return the ajax result. I don't know if this is the best solution.
function ajaxFunction(){
var result='';
$.ajax({
type: "POST",
url: "someUrl",
cache: true,
async: false,
contentType: "application/json; charset=utf-8",
data: "{}",
dataType: "json",
//success: handleHtml,
success: function(data) {
alert('data received');
result=data;
},
error: ajaxFailed
});
return result;
}
Doesn't matter that it's synchronous (though it really shouldn't be). Returning a value from inside the ajax callback will not cause the value to be returned from the containing function.
Using asynchronous ajax is generally a much better idea anyway, but that will force you to create an API that allows its clients to pass in handlers to be called when the ajax request completes. To do that, you'd give your "LoadSomeData" function a parameter. A caller would pass in a function, and your ajax "success" handler would pass on the results (or some transformation of the results; depends on what it is that you're doing) to that callback. It's the same idea as the callbacks used in the ajax call itself.

Categories

Resources