I have a "class"/function called Spotlight. I'm trying to retrieve some information through ajax and assign it to a property of Spotlight. Here is my Spotlight class:
function Spotlight (mId,mName) {
this.area = new Array();
/**
* Get all area information
*/
this.getArea = function () {
$.ajax({
url: base_url +'spotlight/aGetArea',
type: 'POST',
success: function (data) {
this.area = data;
}
});
}
}
I have assigned the object to an array, and it would be difficult to get to it from within Spotlight, so I'm hoping to access everything using 'this.' It appears though that the success function is outside of the class, and I don't know how to make it inside the class.
Is there a way to get the data into the class property using this.area rather than Spotlight.area?
The value of this is dependent on how each function is called. I see 3 ways around this problem:
1. Creating an alias to this
var that = this;
this.getArea = function () {
$.ajax({
url: base_url +'spotlight/aGetArea',
type: 'POST',
success: function (data) {
that.area = data;
}
});
};
2. Using jQuery .ajax context option
this.getArea = function () {
$.ajax({
url: base_url +'spotlight/aGetArea',
type: 'POST',
context : this,
success: function (data) {
this.area = data;
}
});
};
3. Using a bound function as the callback
this.getAreaSuccess = function (data) {
this.area = data;
};
this.getArea = function () {
$.ajax({
url: base_url +'spotlight/aGetArea',
type: 'POST',
success: this.getAreaSuccess.bind(this)
});
};
Well Spotlight.area wouldn't work anyway. You just need to preserve the outer this:
this.area = [];
var theSpotlight = this;
and then in the callback:
theSpotlight.area = data;
When inside the success function, this corresponds to the scope of the success function.
function Spotlight (mId,mName) {
this.area = [];
var scope = this;
/**
* Get all area information
*/
this.getArea = function () {
$.ajax({
url: base_url +'spotlight/aGetArea',
type: 'POST',
success: function (data) {
scope.area = data;
}
});
}
}
Related
On my code I hava a function with 3 nested AJAX calls, in order for it to work I had to set Async=false.
As I have read that Async=false is deprecated I replaced the Async=false with promises.
This is my function before I edited it:
self.getOrders = function (name) {
var orders= [];
var order= function (item, type1, type2) {
var self = this;
self.order= item;
self.type1= type1;
self.type2= type2;
}
$.ajax({
url: "/API/orders/" + name,
type: "GET",
async: false,
success: function (orderResults) {
var mappedOrders = $.map(orderResults, function (orderItem) {
$.ajax({
url: "/API/orders/property/" + orderItem.id + "/type1",
type: "GET",
async: false,
success: function (property1Results) {
$.ajax({
url: "/API/orders/property/" + orderItem.id + "/type2",
type: "GET",
async: false,
success: function (property2Results) {
orders.push(new order(orderItem, property1Results, property2Results));
}
});
}
});
})
}
});
return orders;
This function worked perfectly, I got the data end everything worked fine.
Then I changed the function to use promises instead of Async=false,
this is the edited function, with promises:
//The begin of the function- same as first one
var orders= [];
var firstPromise = $.ajax({
url: "/API/orders/" + name,
type: "GET"
});
$.when(firstPromise).done(function (orderResults) {
var mappedOrders = $.map(orderResults, function (orderItem) {
var secondPromise = $.ajax({
url: "/API/orders/property/" + orderItem.id + "/type1",
type: "GET"
});
$.when(secondPromise).done(function (property1Results) {
var thirdPromise = $.ajax({
url: "/API/orders/property/" + orderItem.id + "/type2",
type: "GET"
});
$.when(thirdPromise).done(function (property2Results) {
orders.push(new order(orderItem, property1Results, property2Results));
});
});
});
});
return orders;
And the function call:
self.populateOrders = function (name) {
var mappedOrders = $.map(self.service.getOrders(name), function (item) {
return new Order(item)
});
self.orders(mappedOrders);
}
The new function is not working, I'm getting back from the firstPromise a wrong json with backslashes, and the returned orders object is empty.
Any idea what am I doing wrong? I spent so much time on it but couldn't figure it out.
Thanks in advance.
Nested ajax calls inside a loop is a hell to manage. You can do it like this.
Create a promise to notify the caller when the whole process is finished
Wait for all the inner ajax calls to resolve
Resolve you main promise to notify the caller
self.getOrders = function (name) {
var mainDeferred = $.Deferred();
var orders = [];
var order = function (item, type1, type2) {
var self = this;
self.order = item;
self.type1 = type1;
self.type2 = type2;
}
$.ajax({
url: "/API/orders/" + name,
type: "GET",
success: function (orderResults) {
var innerwait = [];
var mappedOrders = $.map(orderResults, function (orderItem) {
var ajax1 = $.ajax({
url: "/API/orders/property/" + orderItem.id + "/type1",
type: "GET"
});
var ajax2 = $.ajax({
url: "/API/orders/property/" + orderItem.id + "/type2",
type: "GET"
});
$.when(ajax1, ajax2).done(function (property1Results, property2Results) {
orders.push(new order(orderItem, property1Results[0], property2Results[0])))
});
innerwait.push(ajax1, ajax2);
});;
$.when.apply(null, innerwait) //make sure to wait for all ajax requests to finish
.done(function () {
mainDeferred.resolve(orders); //now that we are sure the orders array is filled, we can resolve mainDeferred with orders array
});
}
});
return mainDeferred.promise();
}
self.populateOrders = function (name) {
self.service.getOrders(name).done(function (orders) { //use .done() method to wait for the .getOrders() to resolve
var mappedOrders = $.map(orders, function (item) {
return new Order(item)
});
self.orders(mappedOrders);
});
}
In the example, note that I use $.when.apply() to wait for an array of deferreds.
A bug recently introduced in chrome 52 (august 2016) can cause this kind of behavior : answers for nested requested are ignored.
Hoppefully, it will not last long.
https://bugs.chromium.org/p/chromium/issues/detail?id=633696
Try to add cache: false
Hello Fellow Developers,
I have a SSN textbox that onblur calls a function which does an ajax request to a Web Method to decide if an employee has been previously hired.
The Web Method returns a TermedEmployee Object to the success callback, but I'm unsure how to parse the object.
$('#<%=FormView1.FindControl("SSNField").ClientID%>').blur(hideValue);
hideValue = function (ev) {
var $this = $(this);
$this.data('value', $this.val());
$('#<%=FormView1.FindControl("hiddenSSN").ClientID%>').val($this.val());
var data2Send = '{"SSN": ' + $this.val() + ' }';
$.ajax({
type: "POST",
url: "AuthforHire.aspx/EmployeeisRehire",
data: data2Send,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
var obj = JSON.stringify(result.d);
if (obj.IsTermed) {
$('#%=RadWindowRehire.ContentContainer.FindControl("TextBoxTermID").ClientID%>').val(arg.d);
var wndWidth = 900;
var wndHeight = 500;
var wnd = window.radopen(null, "RadWindowRehire");
}
},
error: function (xhr) {
alert('Form update failed. '); //error occurred
}
});
Below is a minified version of my webMethod, which works correctly
[System.Web.Services.WebMethod]
public static TermedEmployee EmployeeisRehire(string SSN)
{
TermedEmployee termedEmp = new TermedEmployee();
// Db call to get necessary data.
termedEmp.Name = dr["name"];
termedEmp.TermDate = Convert.ToDateTime(dr["TermDate"].ToString());
......
}
So How Can I extract Name, TermDate,StartDate, ReasonforTerm, etc from the object returned to the callback function?
Thank you in advance!
The first line in your success callback is:
var obj = JSON.stringify(result.d);
Which is trying to serialize what ASP.Net will already have serialized for you.
Change this to:
var obj = result.d;
And you will then have access to obj.Name, obj.TermDate and all the other properties by name.
I am creating new functionality where I build a grid based on Json data returned from Ajax. I have decided I want to encapsulate this functionality within a function, so when I add/update/delete, I can on success retrieve a new representation of the data.
The problem I am having is I want to fill a global array but once my function that uses AJAX ends, I have an Array but no data. This isn't a problem when all the code is within the AJAX call but once I try to separate this in to its own function, it doesn't work as intended.
<script type="text/javascript">
var DataArray = [];
// Use this function to fill array
function retrieveNotes() {
$.ajax({
url: "http://wks52025:82/WcfDataService.svc/GetNotesFromView()?$format=json",
type: "get",
datatype: "json",
asynch:true,
success: function (data) {
returnedData = data;
$.each(data.d, function (i, item) {
DataArray[i] = [];
DataArray[i][0] = item.NotesTitle.trim();
DataArray[i][1] = item.ProfileName.trim();
DataArray[i][2] = item.IsShared;
DataArray[i][3] = item.NameOfUser.trim();
}) // End of each loop
}
});
}
$(document).ready(function () {
retrieveNotes();
DataArray;
</script>
It's asynchronous, so you'll have to wait for the ajax call to finish before you can use the data :
function retrieveNotes() {
return $.ajax({
url: "http://wks52025:82/WcfDataService.svc/GetNotesFromView()?$format=json",
type: "get",
datatype: "json"
});
}
$(document).ready(function () {
retrieveNotes().done(function(data) {
var DataArray = [];
$.each(data.d, function (i, item) {
DataArray[i] = [];
DataArray[i][0] = item.NotesTitle.trim();
DataArray[i][1] = item.ProfileName.trim();
DataArray[i][2] = item.IsShared;
DataArray[i][3] = item.NameOfUser.trim();
});
// you can only use the data inside the done() handler,
// when the call has completed and the data is returned
});
});
This question already has answers here:
JavaScript OOP with jQuery
(2 answers)
Closed 9 years ago.
I have the following code in JavaScript and jQuery with an integrated ajax request.
Question: Why is it possible to call the inner function success1() but it is not possible to call this.success2() ? Any solution proposals for this problem?
function myfuntion() {
this.url = "www.example.com/ajax.php";
var success1 = function (data) {
alert("SUCCESS1");
}
this.success2 = function (data) {
alert("SUCCESS2");
}
this.send = function () {
$.ajax({
type: "POST",
url: this.url,
dataType: "html"
}).done(function (data) {
success1(data);
this.success2(data);
});
}
}
var test = new myfunction().send();
As other commented, the context of this inside the send function is changed, so that's why your success2 function is not calling. You should save myFunction context in a variable and use that variable to refer this context.
Try this:
function myfuntion() {
var self = this; // taking the current context in a variable.
self.url = "www.example.com/ajax.php";
var success1 = function (data) {
alert("SUCCESS1");
}
self.success2 = function (data) {
alert("SUCCESS2");
}
self.send = function () {
$.ajax({
type: "POST",
url: self.url,
dataType: "html"
}).done(function (data) {
success1(data);
self.success2(data);
});
}
}
New to jQuery and having simple yet confusing problem. ha2.
I am writing this normal javascript function with jQuery function reading xml file. How do I assigned value to the prodPrice variable declared on the top? the script keep returning 0 value, but if I alert the value within the jQuery function, I managed to get the value that I wanted.
Thank you guys.
function getPrice(valprodID)
{
var prodPrice=0;
jQuery.ajax({
type: "GET",
url: "products.xml",
dataType : "xml",
success : function(xml)
{
jQuery(xml).find('prod').each(function(){
var prodID = jQuery(this).find('prodID').text();
if(prodID == valprodID)
{
prodPrice = jQuery(this).find('prodPrice').text();
return false;
}
});
}
})
return prodPrice;
}
That's because $.ajax is performed asynchronously.
And it is a great chance for you to learn how to work with $.Deferred
function getPrice(valprodID)
{
var prodPrice=0;
return jQuery.ajax({
type: "GET",
url: "products.xml",
dataType : "xml"
}).pipe(function(xml)
{
jQuery(xml).find('prod').each(function(){
var prodID = jQuery(this).find('prodID').text();
if(prodID == valprodID)
{
return jQuery(this).find('prodPrice').text();
}
});
});
}
Now you call your getPrice() function in this way:
getPrice(someid).done(function(prodPrice) {
// do what you need with prodPrice
});
Here is an example on jsfiddle: http://jsfiddle.net/zerkms/9MgsX/1/
you can do asynchronous as reported by #xdazz, as #zerkms indicated with Deferred, or anonymous functions:
function getPrice(valprodID, fn)
{
var prodPrice=0;
jQuery.ajax({
type: "GET",
url: "products.xml",
dataType : "xml",
success : function(xml)
{
jQuery(xml).find('prod').each(function(){
var prodID = jQuery(this).find('prodID').text();
if(prodID == valprodID)
{
prodPrice = jQuery(this).find('prodPrice').text();
fn(prodPrice);
}
});
}
})
}
getPrice(1, function(prodPrice) {
/* your code */
})
You need to set the async option to false, or you should do your work in the callback function.