I'm somewhat breaking my head over this. I have an ajax call like this:
function genericname()
{
var domain = $('#input').val();
var sendData = {
'domain': domain
};
var promise = $.ajax(
{
type: 'POST',
url: '/functions.php',
data:
{
module: 'modulename',
operation: 'functionname',
parameters: sendData
},
dataType: 'json'
}).promise();
promise.then(function(data)
{
console.log(data);
return data;
});
promise.fail(function(data)
{
console.log(data);
});
}
Now the problem is that when debugging I notice that both promise.then and promise.fail are just skipped. The php proces I am calling to output is true. Actually when I look in the network tab of the debug tools the response says true.
Could anyone explain what the mistake is here?
EDIT: the result being output by the php function is json_encoded
This function is being called in the .then portion of another ajax call
remove .promise at the end of ajax request:
var domain = $('#input').val();
var sendData = {
'domain': domain
};
var promise = $.ajax(
{
type: 'POST',
url: '/functions.php',
data:
{
module: 'modulename',
operation: 'functionname',
parameters: sendData
},
dataType: 'json'
})
The issue is fixed now and here is how I solved it.
The function was required to return a boolean which was used in the if statement in another .then statement of another ajax call to change some html.
In the end I resorted to placing the html changes in the .then portion if this function.
Hope I can help someone with this information.
Related
I'm struggling to implement deferred to get async ajax response. I have this setup:
report.js
function getReport(ref)
{
$.ajax({
url: "report.php",
dataType: 'json',
data: {
ref: ref,
},
success: function(result){
return (result);
}
}
});
}
index.html
<script>
function firstFunction() {
console.log ("start");
getReport(2, 'queue', 'hour', '2018-09-09', '2018-09-10', 'pageviews', 'page', 's1390_5bbb4639ff37');
};
var test = firstFunction();
alert(test);
</script>
Currently I get "undefined" returned straight away because the alert box doesn't wait for the ajax function to run. Using some tutorials online i've tried to implement it this way:
report.js
function getReport(ref)
{
var deferred = $.Deferred();
$.ajax({
url: "report.php",
dataType: 'json',
data: {
ref: ref,
},
success: function(result){
deferred.resolve(result);
}
}
});
returned deferred.promise();
}
index.html
<script>
function firstFunction() {
console.log ("start");
getReport(2, 'queue', 'hour', '2018-09-09', '2018-09-10', 'pageviews', 'page', 's1390_5bbb4639ff37');
};
$.when(getData()).done(function(value) {
alert(value);
});
getData().then(function(value) {
alert(value);
});
</script>
I've obviously made a few mistakes on the way because I'm getting the errors below and I can't seem to get past it:
Uncaught SyntaxError: Unexpected identifier
index2.html:12 start
index2.html:13 Uncaught ReferenceError: getReport is not defined
at firstFunction (index2.html:13)
at index2.html:16
I think the addition of the deferred object in getReport is unnecessary because $.ajax already creates one for you. It might be better to modify your original code this way:
function getReport(ref)
{
return $.ajax({ // Return the deferred object here. It is returned by .ajax()
url: "report.php",
dataType: 'json',
data: {
ref: ref,
} // Remove the callback here.
// You cannot call return in the way you're trying here.
// The context is different and outside of normal flow.
});
}
then in your index file:
<script>
function firstFunction() {
console.log ("start");
// You must return the returned value here as well, otherwise variable `test` is going to be undefined.
return getReport(2, 'queue', 'hour', '2018-09-09', '2018-09-10', 'pageviews', 'page', 's1390_5bbb4639ff37');
};
var test = firstFunction(); // test is now a deferred object
test.done(function(data) {
alert(data);
});
</script>
this is of course just a mockup, but you will get an idea.
This is the first call:
function getData () {
$.ajax{(
type:'GET',
url: url,
success: function (res) {
// logic
// 'res.secret' property value that needs to be passed
}
)}
}
Now, this gets a set of data, that I need to use for another call with POST method later. Let's call it res.secret.
So, next call:
function postData () {
$.ajax{(
type:'POST',
url: url + res.secret,
success: function (res) {
//logic
}
)}
}
What is the best way to pass res.secret to postData() in url property? I can save it in html as data-*, but don't think that is the best way to do it.
Also, please notice that postData() and getData() are in separate .js files.
me being old and not loving promises, I would nest it as so; passing the result of the first on success as a parameter to the second:
function getData () {
$.ajax{(
type:'GET',
url: url,
success: function (res) {
postData(res.secret);
}
)}
}
function postData (theSecret) {
$.ajax{(
type:'POST',
url: url + theSecret,
success: function (res) {
//logic
}
)}
}
this causes sequential and conditional execution.
It's an ideal case for using promises. Here is how I'd right it in ES6 with async/await
(async () => {
// result1 awaits for GET request to be resolved
var result1 = await fetch(url);
// then you pass your 'secret' from result1 to your next POST call
var result2 = await fetch(`${url}${result1.secret}`, {method: 'post'});
})();;
I am using a method in my controller which imports data from an API. This method I am wanted to be called from two locations. First the view (currently working) and secondly a javascript function.
Start of controller method:
[ActionName("ImportRosters")]
[HttpPost]
public ActionResult PerformImportRosterData(int id, int? actualLength, int? rosterLength)
{
var authenticator = Authenticator(id);
var rosters = authenticator.Api().RosterData().ToDictionary(x => x.Id);
var databaseRosterDatas = SiteDatabase.DeputyRosterData.Where(x => x.SiteID == id)
.ToDictionary(x => x.Id);
Javascript Function:
$("#btnDeputyRunNowUpdate").click(function() {
$("#btnRunDeputyNow").modal("hide");
ActualLength = $("#actualRunLength").val();
RosterLength = $("#rosterRunLength").val();
$.ajax({
type: "POST",
url: "/deputy/PerformImportRosterData",
data: { SiteIDRoster, ActualLength, RosterLength }
});
SiteIDRoster = null;
location.reload();
$("#btnRunDeputyNow").modal("hide");
toast.show("Import Successful", 3000);
});
All values are being set but i am getting a 404 error on the url line
POST https://example.org/deputy/PerformImportRosterData 404 ()
I need a way to be able to call this c# method from both html and JS
This can be done if you will modify the URL in your AJAX. It should look something like
url: '<%= Url.Action("YourActionName", "YourControllerName") %>'
or
url: #Url.Action("YourActionName", "YourControllerName")
one more thing, I don't see if you do anything with the result of the call. your script does not have success part
success: function(data) {//do something with the return}
and would be very helpful to have error handler in your call.
full example on how AJAX should look like:
$.ajax({
url: "target.aspx",
type: "GET",
dataType: "html",
success: function (data, status, jqXHR) {
$("#container").html(data);
alert("Local success callback.");
},
error: function (jqXHR, status, err) {
alert("Local error callback.");
},
complete: function (jqXHR, status) {
alert("Local completion callback.");
}
})
For a good tutorial on AJAX read this document
Change after Comment:
my current code is below:
$("#btnDeputyRunNowUpdate").click(function() {
$("#btnRunDeputyNow").modal("hide");
ActualLength = $("#actualRunLength").val();
RosterLength = $("#rosterRunLength").val();
$.ajax({
type: "POST",
url: '<%= Url.Action("PerformImportRosterData", "DeputyController") %>',
data: { SiteIDRoster, ActualLength, RosterLength },
success: function(data) {
console.log(data);
console.log("TESTHERE");
}
});
}
UPDATE:
Noticed one more thing. Your parameters in the controller and AJAX do not match. Please try to replace your a few lines in your AJAX call with:
url: "/deputy/PerformImportRosterData",
data: { id: yourIDValue, actualLength: youractualLengthValue,
rosterLength :yourrosterLengthValue }
remember to set all variable values in javascript , if they have no values set them = to null.
Can you try copy paste code below
$.ajax({
type: "POST",
url: "/deputy/PerformImportRosterData",
data: { SiteIDRoster:999, ActualLength:1, RosterLength:2 }
});
And let me know if it wall cause any errors.
After attempting to solve for a few days, I created a workaround by creating two methods for importing the data. one for the httpPost and the second for import calling from javascript.
Not a great solution but it works. Thanks for your help Yuri
I have read a lot about promises but I'm still not sure how to implement it.
I wrote the folowing AJAX call with async=false in order for it to work, but I want to replace it with promise as I saw that async=false is deprecated.
self.getBalance = function (order) {
var balance;
$.ajax({
url: "/API/balance/" + order,
type: "GET",
async: false,
success: function (data) {
balance = data;
},
done: function (date) {
}
});
return balance;
}
Would you be able to help me? I just need an example to understand it.
As first point, you don't want to set an asynchronous call to false as it will lock the UI.
You could simplify your method returning the ajax object and the handle it as a promise.
self.getBalance = function (orderNumber) {
return $.ajax({
url: "/Exchange.API/accountInfo/balance/" + orderNumber,
type: "GET",
});
};
var demoNumber = 12;
self.getBalance(demoNumber).then(function(data){
console.log(data);
},function(err){
console.log("An error ocurred");
console.log(err);
});
Return promise object from getBalance method:
self.getBalance = function (orderNumber) {
return $.ajax({
url: "/Exchange.API/accountInfo/balance/" + orderNumber,
type: "GET"
});
}
and use it later like this:
service.getBalance().then(function(balance) {
// use balance here
});
I'm currently dealing with refactoring my code, and trying to automate AJAX requests as follows:
The goal is to have a context-independent function to launch AJAX requests. The data gathered is handled differently based on the context.
This is my function:
function ajaxParameter(routeName, method, array, callback){
//Ajax request on silex route
var URL = routeName;
$.ajax({
type: method,
url: URL,
beforeSend: function(){
DOM.spinner.fadeIn('fast');
},
})
.done(function(response) {
DOM.spinner.fadeOut('fast');
callback(response);
})
.fail(function(error){
var response = [];
response.status = 0;
response.message = "Request failed, error : "+error;
callback(response);
})
}
My problem essentially comes from the fact that my callback function is not defined.
I would like to call the function as such (example)
ajaxParameter(URL_base, 'POST', dataBase, function(response){
if(response.status == 1 ){
console.log('Request succeeded');
}
showMessage(response);
});
I thought of returning response to a variable and deal with it later, but if the request fails or is slow, this won't work (because response will not have been set).
That version would allow me to benefit the .done() and .fail().
EDIT : So there is no mistake, I changed my code a bit. The goal is to be able to deal with a callback function used in both .done() and .fail() context (two separate functions would also work in my case though).
As far as I can see there really is nothing wrong with your script. I've neatened it up a bit here, but it's essentially what you had before:
function ajaxParameter (url, method, data, callback) {
$.ajax({
type: method,
url: url,
data: data,
beforeSend: function(){
DOM.spinner.fadeIn('fast');
}
})
.done( function (response) {
DOM.spinner.fadeOut('fast');
if (callback)
callback(response);
})
.fail( function (error){
var response = [];
response.status = 0;
response.message = "Request failed, error : " + error;
if (callback)
callback(response);
});
}
And now let's go and test it here on JSFiddle.
As you can see (using the JSFiddle AJAX API), it works. So the issue is probably with something else in your script. Are you sure the script you've posted here is the same one you are using in your development environment?
In regards to your error; be absolutely sure that you are passing in the right arguments in the right order to your ajaxParameter function. Here's what I am passing in the fiddle:
the url endpoint (e.g http://example.com/)
the method (e.g 'post')
some data (e.g {foo:'bar'})
the callback (e.g function(response){ };)
Do you mean something like this, passing the success and fail callbacks:
function ajaxParameter(routeName, method, array, success, failure) {
//Ajax request on silex route
var URL = routeName;
$.ajax({
type: method,
url: URL,
beforeSend: function () {
DOM.spinner.fadeIn('fast');
}
}).done(function (response) {
DOM.spinner.fadeOut('fast');
success(response);
}).fail(function (error) {
var response = [];
response.status = 0;
response.message = "Request failed, error : " + error;
failure(response);
})
}
Called like:
ajaxParameter(
URL_base,
'POST',
dataBase,
function(response){
//success function
},
function(response){
// fail function
}
);