AJAX sending object with functions throws error at function - javascript

I have the following Ajax:
$.ajax({
type: 'POST',
url: '/Jeopardy/saveCategoryData',
dataType: 'json',
data: {
name: this.name,
questions: this.question_array,
sort_number: this.sort_number,
game_id: game_id
},
success: function (data)
{
this.id = data;
}
});
Update This is the full class the ajax is apart of:
function Category(name, sort_number)
{
this.name = name;
this.sort_number = sort_number;
this.question_array = [];
this.id = 0;
/*
Functions
*/
}
Category.prototype.saveCategory = function()
{
$.ajax({
type: 'POST',
url: '/Jeopardy/createCategory',
dataType: 'json',
data: {
request: 'ajax',
name: this.name,
sort_number: this.sort_number,
game_id: game_id
},
success: function (data)
{
this.id = data;
}
});
$('.category_'+this.sort_number).each(function()
{
$(this).css('opacity', '1');
$(this).addClass('question');
})
}
Category.prototype.submitCategory = function()
{
$.ajax({
type: 'POST',
url: '/Jeopardy/saveCategoryData',
dataType: 'json',
data: {
request: 'ajax',
name: this.name,
questions: this.question_array,
sort_number: this.sort_number,
game_id: game_id
},
success: function (data)
{
this.id = data;
}
});
}
Category.prototype.addQuestion = function(question,index)
{
this.question_array[index] = question
}
Where this.question_array is an array of question objects:
function Question(question, score)
{
this.question = question;
this.score = score;
this.answer = [];
}
Question.prototype.getScore = function()
{
return this.score;
}
Question.prototype.addAnswer = function(answer)
{
this.answer.push(answer)
}
My answer object:
function Answer(answer, is_correct)
{
this.answer = answer;
this.is_correct = is_correct;
}
When my Ajax submits i get an error at the function addAnswer saying: Cannot read property 'push' of undefined
Can anyone tell me why this might be happening (i am fairly new to OOP in JavaScript)
Update create.js (script that controls the objects)
save question function:
function saveQuestion() {
var question = new Question($('#txt_question').val(), current_money);
var array_index = (current_money / 100) - 1;
$('.txt_answer').each(function ()
{
var answer = new Answer($(this).val(), $(this).prev().find('input').is(':checked'));
question.addAnswer(answer); // <-- Add answer
})
if(current_element.find('.badge').length == 0)
{
current_element.prepend('<span class="badge badge-sm up bg-success m-l-n-sm count pull-right" style="top: 0.5px;"><i class="fa fa-check"></i></span>');
}
addQuestionToCategory(question, array_index);
questionObject.fadeOutAnimation();
}
function addQuestionToCategory(question, index) {
switch (current_category_id) {
case "1":
category_1.addQuestion(question, index);
break;
case "2":
category_2.addQuestion(question, index);
break;
case "3":
category_3.addQuestion(question, index);
break;
case "4":
category_4.addQuestion(question, index);
break;
}
}
And the function that calls the ajax on each category object:
function saveGame()
{
category_1.submitCategory();
category_2.submitCategory();
category_3.submitCategory();
category_4.submitCategory();
}
Debug callstack:
Question.addAnswer (question.js:25)
n.param.e (jquery-1.11.0.min.js:4)
Wc (jquery-1.11.0.min.js:4)
Wc (jquery-1.11.0.min.js:4)
(anonymous function) (jquery-1.11.0.min.js:4)
n.extend.each (jquery-1.11.0.min.js:2)
Wc (jquery-1.11.0.min.js:4)
n.param (jquery-1.11.0.min.js:4)
n.extend.ajax (jquery-1.11.0.min.js:4)
Category.submitCategory (category.js:47)
saveGame (create.js:116)
onclick (create?game_id=1:182)
*UPDATE
Okay something odd is going on if i change the addAnswer function to the following:
Question.prototype.addAnswer = function(answer)
{
if(this.answers != undefined)
{
this.answers.push(answer)
}
}
It works fine?

Looks like Alexander deleted his response, here is what I would suggest:
function Question(question, score)
{
this.question = question;
this.score = score;
this.answer = [];
}
Question.prototype.getScore = function()
{
return this.score;
}
Question.prototype.submitQuestion = function()
{
}
Question.prototype.addAnswer = function(answer)
{
this.answer.push(answer)
}

Related

Unable to update class variable after ajax call

After getting two integer upon the ajax request has been completed, this.N and this.M are not getting set by storeDims() even if the dims has correctly been decoded. So it seems that I cannot acces this.N and this.M declared in the constructor.
This is the code
class MapModel {
constructor() {
this.N; // need to initialize this after an ajax call
this.M;
this.seats = new Array();
this.remote_seats = new Array();
}
init(callback) {
let _this = this;
$.when(
_this.getDims(),
_this.getSeats(),
).then(this.initMap(callback))
}
initMap(callback) {
console.log(this.N); // prints undefined
console.log(this.M); // this as well
callback(this.N, this.M, this.seats);
}
getDims() {
let _this = this;
$.ajax({
url: 'src/php/data.php',
type: 'POST',
data: {action: 'getDims'},
success: function (result) {
let dims = JSON.parse(result); // dims[0] = 10, dims[1] = 6
_this.storeDims(dims);
}
});
}
storeDims(dims) {
console.log(dims);
this.N = parseInt(dims[0]);
this.M = parseInt(dims[1]);
console.log(this.N);
console.log(this.M);
}
getSeats() {
let _this = this;
$.ajax({
url: 'src/php/data.php',
type: 'POST',
data: {action: 'getSeats'},
success: function (result) {
let seats = JSON.parse(result);
_this.storeSeats(seats);
}
});
}
storeSeats(seats) {
this.remote_seats = seats;
console.log(this.remote_seats);
}
}
You need to return the ajax promises from the getDms and getSeats functions
getDims() {
let _this = this;
return $.ajax({
url: 'src/php/data.php',
type: 'POST',
data: {action: 'getDims'},
success: function (result) {
let dims = JSON.parse(result); // dims[0] = 10, dims[1] = 6
_this.storeDims(dims);
}
});
}
you can even pass the values directly to the initMap
init(callback) {
let _this = this;
$.when(
_this.getDims(),
_this.getSeats()
).then(function(dims,seats) {_this.initMap(dims,seats,callback)})
}
initMap(dimsRaw,seatsRaw, callback) {
let dims = JSON.parse(dimsRaw);
console.log(dims[0]);
console.log(dims[1]);
callback(dims[0], dims[1], this.seats);
}
The init promise callback is being called on the chain declaration, try adding a function wrapper:
init(callback) {
let _this = this;
$.when(
_this.getDims(),
).then(function() {_this.initMap(callback)})
}

How to determine if the java script function still running?

I have concern regarding of javascript function, The question is there any indicator to determine if the javascript function still on going or still running? because I have problem on inserting hundred of items inserting in the database. I want to condition if the javascript function still on going the insertion will stay until the condition met the else if the javascript function is not running or done, it will automatically redirect to the other page.
In my onclick of my jquery I insert the javascript function.
$('#add_to_cart').on('click', function() {
orders = [];
menu = undefined;
$('.tbody_noun_chaining_order').children('tr').each(function() {
$row = $(this);
if ($row.hasClass('condimentParent')) {
if (menu) {
orders.push(menu);
}
menu = {
'total': $row.find('.total').text(),
'name': $row.find('.parent_item').text(),
'customer_id': customer_id,
'condiments': {
'Item': [],
'Qty': [],
'Total': []
}
};
} else if ($row.hasClass('editCondiments')) {
menu.condiments.Item.push($row.find('.child_item').text());
menu.condiments.Qty.push($row.find('.condiments_order_quantity').text());
menu.condiments.Total.push($row.find('.total').text());
}
});
if (menu) {
orders.push(menu);
}
storeOrder(orders)
});
My Javascript Function
function storeOrder(data) {
var customer_id = $('#hidden_customer_id').val();
var place_customer = $('#place_customer').text();
$id = "";
$total_amount = $('.total_amount').text();
$append_customer_noun_order_price = $('.append_customer_noun_order_price').text();
$tax_rate = $('.rate_computation').text();
$delivery_rate = $('.del_rate').text();
var sessionTransactionNumber_insert = localStorage.getItem('sessionTransactionNumber');
$.ajax({
url:'/insert_customer_order_properties',
type:'POST',
data:{
'hidden_customer_id': customer_id,
'hidden_customer_address': place_customer,
'sessionTransactionNumber': sessionTransactionNumber_insert
},
success:function(data) {
$id = data[0].id;
$.ajax({
url:'/insert_customer_payment_details',
type:'POST',
data:{
'hidden_customer_id': customer_id,
'total_amount': $total_amount,
'customer_sub_total': $append_customer_noun_order_price,
'tax_rate': $tax_rate,
'id_last_inserted': $id
},
success:function(data) {
localStorage.removeItem('sessionTransactionNumber');
}
})
}
})
for (var num in orders) {
$.ajax('/insert_wish_list_menu_order', {
type: 'POST',
context: orders[num].condiments,
data: {
'append_customer_noun_order_price': orders[num].total,
'append_customer_noun_order': orders[num].name,
'customer_id': customer_id
},
success: function(orderNumber) {
$order_number = orderNumber[0].id;
$.ajax({
url:'/insert_customer_order_details_properties',
type:'POST',
data:{
'order_number': $order_number,
'data_attribute_wish_order_id': $id,
},
success:function(data) {
console.log(data);
}
})
if (orderNumber !== undefined) {
$.ajax('/insert_wish_list_menu_belong_condiments', {
context: orderNumber,
type: 'POST',
data: {
'ParentId': orderNumber,
'Item': this.Item,
'Qty': this.Qty,
'Total': this.Total
},
success: function(result) {
console.log(result);
},
})
}
}
})
}
}

Only one alert for multiple execution in Ajax

I am working rails application.i need to get status of the each selected device.I am able to achieve this but after executing i am putting alert "Successfully created execution record".For every mac selection it is showing alert message.I need to give one alert in end of execution.I am calling display_result in call_endpoint method.Since it is an Ajax call,it is giving alert for every execution.i don't how to limit to single alert for this.
function display_result() {
$('#http_status').html("");
$('#http_status').append(result["response"].status);
if (result["response"].status == "404") {
console.log("HTTP 404");
$('#response_div').addClass("bs-callout-warning");
} else if (result["response"].status == "520") {
console.log("HTTP 502");
$('#response_div').addClass("bs-callout-danger");
} else {
console.log("HTTP 200");
$('#response_div').addClass("bs-callout-success");
if (result["response"].status == "200") {
// $('.loader').show();
$('#cover-spin').show();
$.ajax({
method: "GET",
dataType: "text",
url: "create_execution",
data: {
http_status: result["response"].status,
mac_address: mac,
},
success: function (execution_record_id) {
$('#cover-spin').hide();
alert('Successfully created execution record");
}
});
}
function call_endpoint() {
var values = new Array();
webpa = $('#Device-PA').is(":visible");
rpil = $('#Device-SN').is(":visible");
groupselect = $('#Group-Select').is(":visible");
parameter_name = $('#tr_object').val();
if (webpa) {
$.each($("input[name='checkBox[]']:checked").closest("td").next("td"), function () {
values.push($(this).text().trim())
});
m = values.length
} else {
$.each($("input[name='checkBox[]']:checked").closest("td").next("td"), function () {
values.push($(this).text().trim())
});
m = values.length
}
serialnumber = $('#pa_serialnumber').val();
oid = $('#sn_serialnumber').val();
protocol = {
pa: pa,
sn: sn,
}
if (pa) {
for (var i = 0; i < m; i++) {
(function () {
var macAdd = values[i];
$.ajax({
method: "GET",
url: "get_object",
dataType: "json",
data: {
parameter: parameter_name,
mac: macAdd,
protocol: protocol,
serialnumber: serialnumber,
},
success: function (result) {
console.log(result);
NProgress.done();
console.log("result for webpa");
display_result();
},
statusCode: {
404: function () {
console.log("Call failed");
}
}
});
})();
}
}
Below is changed code..
Copy below code as it is.
function display_result(total,current) {
$('#http_status').html("");
$('#http_status').append(result["response"].status);
if (result["response"].status == "404") {
console.log("HTTP 404");
$('#response_div').addClass("bs-callout-warning");
} else if (result["response"].status == "520") {
console.log("HTTP 502");
$('#response_div').addClass("bs-callout-danger");
} else {
console.log("HTTP 200");
$('#response_div').addClass("bs-callout-success");
if (result["response"].status == "200") {
// $('.loader').show();
$('#cover-spin').show();
$.ajax({
method: "GET",
dataType: "text",
url: "create_execution",
data: {
http_status: result["response"].status,
mac_address: mac,
},
success: function (execution_record_id) {
$('#cover-spin').hide();
if(total == current)
{
alert('Successfully created execution record");
}
}
});
}
}
}
function call_endpoint() {
var values = new Array();
webpa = $('#Device-PA').is(":visible");
rpil = $('#Device-SN').is(":visible");
groupselect = $('#Group-Select').is(":visible");
parameter_name = $('#tr_object').val();
if (webpa) {
$.each($("input[name='checkBox[]']:checked").closest("td").next("td"), function () {
values.push($(this).text().trim())
});
m = values.length
} else {
$.each($("input[name='checkBox[]']:checked").closest("td").next("td"), function () {
values.push($(this).text().trim())
});
m = values.length
}
serialnumber = $('#pa_serialnumber').val();
oid = $('#sn_serialnumber').val();
protocol = {
pa: pa,
sn: sn,
}
if (pa) {
for (var i = 1; i <= m; i++) {
(function () {
var macAdd = values[i];
$.ajax({
method: "GET",
url: "get_object",
dataType: "json",
data: {
parameter: parameter_name,
mac: macAdd,
protocol: protocol,
serialnumber: serialnumber,
},
success: function (result) {
console.log(result);
NProgress.done();
console.log("result for webpa");
display_result(m,i);
},
statusCode: {
404: function () {
console.log("Call failed");
}
}
});
})();
}
}
}
result and mac is not defined in display_result function. result appears intended to be the resulting value of jQuery promise object returned from $.ajax(). Am not certain what mac is indented to be.
You can substitute $.when() and $.map() for for loop, return a jQuery promise object from call_endpoint(), include error handling, chain .then() to call_endpoint() call to execute alert() once.
function call_endpoint() {
return $.when.apply($, $.map(values, function(macAdd) {
return $.ajax().then(display_result)
}))
}
callEnpoint()
.then(function() {
alert('Successfully created execution record');
}, function(jqxhr, textStatus, errorThrown) {
console.error(errorThrown)
});
function display_result(reuslt) {
..
if (if (result["response"].status == "200")) {
return $.ajax() // remove `alert()` from `success`
}
return;
}

How to wait untill for (append) finished and then show result javascirpt / jquery

I have a function that renders 5 images, and pagination. This function used ajax for getting data.
It works well, but when I using the pagination, I can see the process of 'creating' HTML.
I want to add a loading.gif, until all the HTML finished loading, and show all the results
function getImages(init, buttonPaging) {
var data = {};
if (init) {
data["int"] = "1";
} else {
data["int"] = $(buttonPaging).text();
}
$.ajax({
type: "POST",
url: '#Url.Action("GetImages", "Image")',
data: JSON.stringify(data),
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
},
contentType: "application/json",
dataType: "json",
success: function (data) {
if (data.success) {
$('#imgList').children().remove();
for (var i = 0; i < data.imageList.length; i++) {
(function (img) {
$('#imgList').append(drawList(img, data.baseUrl));
})(data.imageList[i]);
}
$('#pagingList').children().remove();
for (var i = 0; i < data.pagingInfo.totalPages; i++) {
(function (paging) {
var isCurrentPage = false,
index = i;
index++;
if (paging.currentPage == index) {
isCurrentPage = true;
}
$('#pagingList').append(drawPaging(index, isCurrentPage));
})(data.pagingInfo);
}
} else {
errors += data.error;
}
},
error: function () {
errors += 'Please contact with administrator - img list at edit product';
alert(errors);
}
});
}
I saw tutorials about promises and callbacks, but I'm not good at it and I don't know how to rewrite my code for those. Is there another way to solve the issue ?
solution: It may come in handy for other:
function hideLoader() { setTimeout(function () { $('.loader-sm').hide(); }, 750); }
function showLoader() { $('.loader-sm').show(); }
function hideList() { $('#imgList').hide(); }
function showList() { setTimeout(function () { $('#imgList').show(200); }, 750); }
success: function () {
if (data.success) {
//do something
} else {
showList();
hideLoader();
}
},
error: function () {
showList();
hideLoader();
},
complete: function () {
showList();
hideLoader();
}
have a class for show loading image icon and place it in the block itself and hide it once completed. have a look at the below sample. it may helpful to you.
beforeSend: function() {
$('#imgList').addClass('loading');
},
success: function(data) {
$("#imgList").removeClass('loading');
},
error: function(xhr) { // if error occured
$("#imgList").removeClass('loading');
},
complete: function() {
$("#imgList").removeClass('loading');
}
otherwise you can have a loader div block show the block on beforesend() and hide it in success / complete.
You can do like this i am not sure about but it will help you
function getImages(init, buttonPaging) {
var data = {};
if (init) {
data["int"] = "1";
} else {
data["int"] = $(buttonPaging).text();
}
let promise = new Promise(function(resolve, reject) {
//add your code for add loading.gif
$.ajax({
type: "POST",
url: '#Url.Action("GetImages", "Image")',
data: JSON.stringify(data),
beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val()); },
contentType: "application/json",
dataType: "json",
success: function (data) {
if (data.success) {
$('#imgList').children().remove();
for (var i = 0; i < data.imageList.length; i++) {
(function (img) {
$('#imgList').append(drawList(img, data.baseUrl));
})(data.imageList[i]);
}
$('#pagingList').children().remove();
for (var i = 0; i < data.pagingInfo.totalPages; i++) {
(function (paging) {
var isCurrentPage = false,
index = i;
index++;
if (paging.currentPage == index) { isCurrentPage = true; }
$('#pagingList').append(drawPaging(index, isCurrentPage));
})(data.pagingInfo);
}
resolve();
} else {
errors += data.error;
resolve();
}
},
error: function () {
errors += 'Please contact with administrator - img list at edit product';
alert(errors);
resolve();
}
});
}
promise.then(
result => alert("done"), // remove loading.gif
);
}

Does jQuery.ajax() not always work? Is it prone to miss-fire?

I have an $.ajax function on my page to populate a facility dropdownlist based on a service type selection. If I change my service type selection back and forth between two options, randomly the values in the facility dropdownlist will remain the same and not change. Is there a way to prevent this? Am I doing something wrong?
Javascript
function hydrateFacilityDropDownList() {
var hiddenserviceTypeID = document.getElementById('<%=serviceTypeID.ClientID%>');
var clientContractID = document.getElementById('<%=clientContractID.ClientID%>').value;
var serviceDate = document.getElementById('<%=selectedServiceDate.ClientID%>').value;
var tableName = "resultTable";
$.ajax({
type: 'POST',
beforeSend: function () {
},
url: '<%= ResolveUrl("AddEditService.aspx/HydrateFacilityDropDownList") %>',
data: JSON.stringify({ serviceTypeID: TryParseInt(hiddenserviceTypeID.value, 0), clientContractID: TryParseInt(clientContractID, 0), serviceDate: serviceDate, tableName: tableName }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
a(data);
}
,error: function () {
alert('HydrateFacilityDropDownList error');
}
, complete: function () {
}
});
}
function a(data) {
var facilityDropDownList = $get('<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>');
var selectedFacilityID = $get('<%= selectedFacilityID.ClientID%>').value;
var tableName = "resultTable";
if (facilityDropDownList.value != "") {
selectedFacilityID = facilityDropDownList.value;
}
$(facilityDropDownList).empty();
$(facilityDropDownList).prepend($('<option />', { value: "", text: "", selected: "selected" }));
$(data.d).find(tableName).each(function () {
var OptionValue = $(this).find('OptionValue').text();
var OptionText = $(this).find('OptionText').text();
var option = $("<option>" + OptionText + "</option>");
option.attr("value", OptionValue);
$(facilityDropDownList).append(option);
});
if ($(facilityDropDownList)[0].options.length > 1) {
if ($(facilityDropDownList)[0].options[1].text == "In Home") {
$(facilityDropDownList)[0].selectedIndex = 1;
}
}
if (TryParseInt(selectedFacilityID, 0) > 0) {
$(facilityDropDownList)[0].value = selectedFacilityID;
}
facilityDropDownList_OnChange();
}
Code Behind
[WebMethod]
public static string HydrateFacilityDropDownList(int serviceTypeID, int clientContractID, DateTime serviceDate, string tableName)
{
List<PackageAndServiceItemContent> svcItems = ServiceItemContents;
List<Facility> facilities = Facility.GetAllFacilities().ToList();
if (svcItems != null)
{
// Filter results
if (svcItems.Any(si => si.RequireFacilitySelection))
{
facilities = facilities.Where(f => f.FacilityTypeID > 0).ToList();
}
else
{
facilities = facilities.Where(f => f.FacilityTypeID == 0).ToList();
}
if (serviceTypeID == 0)
{
facilities.Clear();
}
}
return ConvertToXMLForDropDownList(tableName, facilities);
}
public static string ConvertToXMLForDropDownList<T>(string tableName, T genList)
{
// Create dummy table
DataTable dt = new DataTable(tableName);
dt.Columns.Add("OptionValue");
dt.Columns.Add("OptionText");
// Hydrate dummy table with filtered results
if (genList is List<Facility>)
{
foreach (Facility facility in genList as List<Facility>)
{
dt.Rows.Add(Convert.ToString(facility.ID), facility.FacilityName);
}
}
if (genList is List<EmployeeIDAndName>)
{
foreach (EmployeeIDAndName employeeIdAndName in genList as List<EmployeeIDAndName>)
{
dt.Rows.Add(Convert.ToString(employeeIdAndName.EmployeeID), employeeIdAndName.EmployeeName);
}
}
// Convert results to string to be parsed in jquery
string result;
using (StringWriter sw = new StringWriter())
{
dt.WriteXml(sw);
result = sw.ToString();
}
return result;
}
$get return XHR object not the return value of the success call and $get function isn't synchronous so you should wait for success and check data returned from the call
these two lines do something different than what you expect
var facilityDropDownList = $get('<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>');
var selectedFacilityID = $get('<%= selectedFacilityID.ClientID%>').value;
change to something similar to this
var facilityDropDownList;
$.ajax({
url: '<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>',
type: 'get',
dataType: 'html',
async: false,
success: function(data) {
facilityDropDownList= data;
}
});

Categories

Resources