Asynchronous ajax call causing issue in KnockOutjs - asynchronous

I have a button on click of that i am calling something like :
ViewModel:
self.MyArray = ko.observableArray();
self.remove = function(c) {
ko.utils.arrayForEach(c.sData(), function(ser) {
if (ser.Check() == true) {
self.MyArray.push(service);
count++;
}
});
if (count) {
$.ajax({
url: "/api/LoadCustomer/?reason=" + reason,
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(self.MyArray),
success: function(data) {
ko.utils.arrayForEach(self.MyArray(), function(removedata) {
c.sData.remove(removedata);
});
}
});
self.MyArray([]);
}
};
If i include async:false in my ajax call i get everything fine but if i didn't include async (its default property is true) i dont know somehow in my success function of ajax call self.MyArray() remains Empty but its not the case if i keep it false (Awkward).
Sometimes i fear like if i have series of ajax calls with async:true while loading into a observable array(OnLoad) there may be a slight chance of misplacement of data .
Help me understand .

The reason your observable array MyArray is empty sometimes is because this line of code self.MyArray([]); executing before the ajax call is done. How about this instead -
if (count) {
$.ajax({
url: "/api/LoadCustomer/?reason=" + reason,
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(self.MyArray),
success: function (data) {
ko.utils.arrayForEach(self.MyArray(), function (removedata) {
c.sData.remove(removedata);
});
},
complete: function() { // complete fires after success and error callbacks
self.MyArray([]); // empty the array no matter what happens (error or success)
}
});
}

Related

Ajax data not passing to controller

I have a problem where the data in the ajax isn't passing the sessionStorage item. I have tried using JSON.stringify and added contentType: 'application/json' but still it's not passing. Can this be done using POST method? Also, I have debugged and returned those sessionStorages, hence the problem isn't because the sessionStorge doesn't contain data.
Here my function:
function functionA() {
$.ajax({
url: URLToApi,
method: 'POST',
headers: {
sessionStorage.getItem('token')
},
data: {
access_token: sessionStorage.getItem('pageToken'),
message: $('#comment').val(),
id: sessionStorage.getItem('pageId')
},
success: function () {
$('#success').text('It has been added!"');
},
});
}
Check below things in Controller's action that
there should be a matching action in controller
name of parameter should be same as you are passing in data in ajax
Method type should be same the ajax POST of the action in controller.
function AddPayment(id, amount) {
var type = $("#paymenttype").val();
var note = $("#note").val();
var payingamount = $("#amount").val();
$('#addPayment').preloader();
$.ajax({
type: "POST",
url: "/Fixed/AddPayment",
data: {
id: id,
amount: payingamount,
type: type,
note: note
},
success: function (data) {
}
});
}
Here is the working code from my side.
Check with this, and for the header part you need to get it from the Request in action
The solution to this problem has been found. The issue was the sessionStorage, hence I've passed it directly to the URL and now it working as follows:
function functionA() {
$.ajax({
url: 'http://localhost:#####/api?id=' + sessionStorage.getItem('pageId') + '&access_token=' + sessionStorage.getItem('pageToken') + '&message=' + $('#comment').val(),
method: 'POST',
headers: {
sessionStorage.getItem('token')
},
success: function () {
$('#success').text('It has been added!"');
},
});
}

How to send ember js header request without ember data

I'm trying to make a call to the wp-api.org plugin for Wordpress. I want to show all users, and I want to use cookie authentication. Therefore I need to send a header request as explained on the website like this:
options.beforeSend = function(xhr) {
xhr.setRequestHeader('X-WP-Nonce', WP_API_Settings.nonce);
if (beforeSend) {
return beforeSend.apply(this, arguments);
}
};
The following code I am using in my model:
App.UsersRoute = Ember.Route.extend({
model: function() {
return Ember.$.ajax({
url: "http://myurl.com/wp-json/users/",
type: "GET",
dataType: "json",
data: JSON.stringify({}),
beforeSend: xhr.setRequestHeader('X-WP-Nonce', WP_API_Settings.nonce);
});
}
});
At the moment the site returns this message because the authentication failed, but I am logged in and cookies are set:
[{"code":"json_user_cannot_list","message":"Sorry, you are not allowed to list users."}]
This should work:
App.UsersRoute = Ember.Route.extend({
model: function() {
return Ember.$.ajax({
url: "http://myurl.com/wp-json/users/",
type: "GET",
dataType: "json",
data: JSON.stringify({}),
beforeSend: function(xhr) {
xhr.setRequestHeader('X-WP-Nonce', WP_API_Settings.nonce);
}
});
}
});
the beforeSend property needs to be a function that is passed xhr, like in your first example, in your second code snippet xhr will be undefined.

Just another jQuery AJAX not POST parameters correctly

I've googled many similar situations, but none of them could solve my problem. Please take a look at my code:
JavaScript:
$.ajax({
type: 'POST',
url: 'alarmInfo.aspx',
data: {request:'BasicGpaInfo'},
dataType: "json",
success: function (data) {
alert(data);
},
error: function () {
alert("Error in loading alarm information!");
}
});
ASP.NET:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Form["request"] == "BasicGpaInfo")
{
Response.Write(BasicGpaInfo());
}
else
{
Response.Write("Nothing");
}
}
This always returns "Nothing" and break point tells that Request.Form is null. And I have tried with GET and Request.QueryString which gives the same situation.
I guess there's something wrong with data in ajax function and I've tried with the following things that won't help:
data: $.param({request:'BasicGpaInfo'})
data: "{request:'BasicGpaInfo'}"
data: {request:'BasicGpaInfo'}
It won't work on all Web Browsers.
Please give some advice. Thanks!
I tested your code and it runs fine. However it always returns "Error in loading alarm information!" because you are not returning Json from the server.
Javascript is fine, once you return json, it will go into success.
You are returning the whole page, and your ajax method is getting the whole html instead of Json from BasicGpaInfo()
try putting a breakpoint in alert, and you will see all the data come inside data
error: function (data) {
alert("Error in loading alarm information!");
}
alternatively try
error: function (data) {
alert(data);
}
Here is the full code
$.ajax({
type: 'POST',
url: 'Default.aspx/BasicGpaInfoWebMethod',
data: { request: 'BasicGpaInfo' },
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
alert(data);
},
error: function (data) {
alert("Error in loading alarm information!");
//alert(data); // uncomment to see the whole response
}
});
and your webmethod will be :
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string BasicGpaInfoWebMethod(string request)
{
return request;
}
Try this JSON.stringify before post. For using JSON.stringify in IE<=7 include json2.js file from json.org
$.ajax({
type: 'POST',
url: 'alarmInfo.aspx',
data: JSON.stringify({ request: 'BasicGpaInfo'}),
dataType: "json",
success: function (data) {
alert(data);
},
error: function () {
alert("Error in loading alarm information!");
}
});

How can I return a value from a function that uses a jQuery ajax call?

I have the following Javascript function that makes a call to an Asp.Net WebMethod that returns true if a username already exists and false if it does not.
The following will give me the correct answer in an alert box but if I change the
alert(result.d) to return result.d
the result of the function is always undefined.
How can I get the function that the Ajax call is contained in to return a value based on the response from the WebMethod?
function doesEnteredUserExist() {
var valFromUsernameBox = $("#txtUserName").val();
var jsonObj = '{username: "' + valFromUsernameBox + '"}';
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: jsonObj,
dataType: 'json',
async: false,
url: 'AddNewUser.aspx/IsUserNameValid',
success: function (result) {
alert(result.d);
},
error: function (err) {
alert(err);
}
});
}
The thing to note is that the ajax function is non blocking. You specify two callback functions, one for success and one for error, one of these functions will get executed when the underlying request is finished.
Your doesEnteredUserExist does not wait for the ajax call to complete, and thus, the return value of the function is undefined.
The proper way to continue execution based on the result of your call is to break your functionality out into a separate function, and call that from your success function.
Ajax is asynchronous so once the function "doesEnteredUserExist" returns, the ajax call is not yet finished. Then later in the success callback you have the value. From there you should continue with your code and display the info to the user.
Store the value of result.d in a variable, then use it for whatever you would like.
Change this:
success: function (result) {
alert(result.d);
},
to this:
success: function (result) {
var resultString = result.d;
},
Now whenever you need result.d, just use the variable resultString. Basically, the ajax call is the only thing that can call the function that you wanted to return the value for, so you need to store that value when the function is called.
Maybe give this a bash
function onSucess (data) {
alert(data.d);
}
function doesEnteredUserExist() {
var valFromUsernameBox = $("#txtUserName").val();
var jsonObj = '{username: "' + valFromUsernameBox + '"}';
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: jsonObj,
dataType: 'json',
async: false,
url: 'AddNewUser.aspx/IsUserNameValid',
success: onSucess,
error: function (err) {
alert(err);
}
});
}
I am guessing that you are trying to set result.d which is out of scope from the call which is why the alert (result.d) works as its in scope.
I may be getting the wrong end of the stick, you could use a global variable (not recommended), set that in the ajax return which you could then read from your function.
May need a bit more info or clarity on what your trying to achieve, as I read the question a couple of ways.
I normally do this (havent tested this):
function ajaxLoad(callback)
$.ajax({
type: 'POST',
async: true,
url: 'url.aspx',
data: d,
cache: false,
contentType: 'application/json',
dataType: 'json',
error: function (xmlHttpRequest, textStatus, errorThrown) {
//error stuff
},
success: function (data) {
if (typeof callback == 'function') { [callback(data)]; }
}
});
}
function callback(data)
{
alert(data);
}
call the function using
ajaxLoad('callback');
something like that!
Inside your success callback function if you return some value it doesn't set the return value for it's parent function. In this case the parent function is $.ajax and it always returns a jqXHR deferred object.
If you are using jQuery 1.5 or later the you can use deferreds. The idea is to save the jqXHR object returned from the AJAX request and wait for it to complete before returning it's value:
var jqXHR = $.ajax({...});
$.when(jqXHR).then(function (result) {
return result.d
});
Docs for $.when(): http://api.jquery.com/deferred.when
An example of doing this would be to return the jqXHR object from your function and then wait for the AJAX request to resolve outside the function:
function doesEnteredUserExist() {
return $.ajax({...});
}
$.when(doesEnteredUserExist).then(function (result) {
//you can access result.d here
});
As #timing has mentioned, by the time the value is returned from thefunction, the ajax call is not complete so everytime you get the undefined.
This is not a solution to the problem, but an alternative method you can try for displaying it would be instead of returning the value, just update the innerHTML of some element like div with the returned text.Below is what I mean:
function doesEnteredUserExist() {
var valFromUsernameBox = $("#txtUserName").val();
var jsonObj = '{username: "' + valFromUsernameBox + '"}';
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: jsonObj,
dataType: 'json',
async: false,
url: 'AddNewUser.aspx/IsUserNameValid',
success: function (result) {
//alert(result.d);
if(result.d==true){ //Just a check for the value whether true or 1 etc..
$("#notifications").html('Username Already Exists'); // Have a div where you can display the message (named it notifications here) , update the notifications div text to notify the user
}else{
$("#notifications").html('Username is Available');
}
},
error: function (err) {
alert(err);
}
});
}
This seems a good example of $.Deferred object usage
the idea is quite simple (really, I promise, :) see steps on the code)
Create a new deferred object
Make your ajax call. If result is false you will reject the deferred otherwise you will resolve it (you could reject it also on error ajax callback)
return the promise
Use .when() helper to check the status of the promise.
I create a fiddle which return randomically true or false in the response
function checkUserExist() {
var dfd = $.Deferred(); /* step 1 */
$.ajax({
url: "/echo/json/",
data: {
"json": JSON.stringify({d: (Math.random() < 0.5) })
},
type: "POST",
success: function (data) {
console.log("result (inside ajax callback) ", data.d);
if (!data.d) { dfd.reject() } else { dfd.resolve(); } /* step 2 */
},
error : ...
});
/* step 3 */
return dfd.promise();
}
$.when(checkUserExist()) /* step 4 */
.fail(function() { console.log("user don't exist (inside fail)"); })
.done(function() { console.log("user already exist (inside done)"); })
fiddle url : http://jsfiddle.net/Gh9cN/
(note: I've changed some internal details so to make it work on jsfiddle)

Adding JSON results to a drop down list with JQUERY

I'm making a call to a page method via AJAX in my ASP.NET application via JQUERY's AJAX method e.g.
$.ajax({
type: "POST",
url: "page.aspx/GetDropDowns",
data: "{'aId':'1'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
alert(msg.d);
},
error: function() {
alert('Error getting page');
}
I'll be returning the results in JSON format, whereby I will be populating a drop down. I could do this part myself but I want to know if there is any built in magic in JQuery for processing JSON results or if there are any good utility scripts for this sort of thing.
There is little jQuery itself can help you with populating dropdown. You just need to create HTML and append it to your dropdown.
I'm not sure what is the format of your data so I'm assuming it's an object where keys should be dropdown's keys and values should be dropdown's values.
I also prefer using $.post then $.ajax as it has a clearer structure for me.
$.post('page.aspx/GetDropDowns', {'aId': '1'}, function (data, status) {
if (status === 'success') {
var options = [];
for (var key in data) {
options.push('<option value="' + key + '">' + data[key] + '</option>');
}
$('#yourId').append(options.join(''));
} else {
alert('error');
}
}, 'json');
In the past I have used a plugin when working with dropdowns.
http://www.texotela.co.uk/code/jquery/select
Request the JSON data:
//Get the JSON Data
$.getJSON(url, function(json) {
PopulateDropDownFromJson(json, "#element");
});
and then just pass the JSON into a function that uses the plugin above
function PopulateDropDownFromJson(json, element){
$.each(json, function() {
$(element).addOption(this[valueText], this[displayText], false);
});
}

Resources