ajax fallback when no internet connection - javascript

The following code submits data to the server. The data is actually stored in the localStorage before submit to server. This is due to my requirement for the user to be able to use my system without an internet connection.
The problem is that when there is no internet connection, obviously it cant post the data to the server. What should I do in this situation?
$('#btnSync').on('click', function(e) {
var my_data = {};
var my_value = [];
for ( var i = 0, len = localStorage.length; i < len; ++i ) {
if((localStorage.key( i ).includes('set'))){
var lsItems = JSON.parse(localStorage.getItem( localStorage.key( i ) ));
allItems[localStorage.key( i )] = lsItems;
}
}
$.ajax({
url: "action.php",
type: "POST",
data: {'action':'btnSync','allItems':allItems},
dataType: "json",
success: function(data) {
$.notify(
{
message: data.message
},
{
type: data.status,
placement: {
from: "top",
align: "left"
},
newest_on_top: true,
delay: 0
}
);
},
error: function(data){
$.notify(
{
message: 'Unexpected error occured, please kindly contact System Administrator'
},
{
type: 'danger',
placement: {
from: "top",
align: "left"
},
newest_on_top: true,
delay: 0
}
);
}
});
});

you can check whether connection/server is up using a similar ajax call. Look for
statusCode.status == 0
in error and give destination unreachable/Internet down notice to user. You can create this ajax call as a promise in a function and use that before all your ajax calls, and ask user to connect to the Internet then retry.

Related

Kendo Grid Destroy Command sending entire HTML page to schema response -- Uncaught TypeError: Cannot read property 'results' of undefined

I am trying to add a Delete button to each row in my kendo grid. I added the destroy command to the grid configuration and have the Delete button showing, but when I click it, I receive a console error -- Uncaught TypeError: Cannot read property 'results' of undefined. This is referring to a line in the schema.parse that reads:
for (var i = 0, il = response.d.results.length; i < il; i++)
It's saying response is undefined. when I console.log(response) and it turns out that the entire html page is being sent in the response.
This doesn't make sense to me, because when I console.log(options) in transport.destroy and console.log(data) in the parameterMap, both console.logs show me in JSON format the row that needs to be deleted and includes the ID.
So why is it being transported to the schema as the entire html page? console.log(response) in the schema starts with <DOCTYPE !HTML> etc. and includes the whole page. Can anyone tell me why this is?
and yes, I have already included editable: "inline" in the grid configuration. Thanks
var ds = new kendo.data.DataSource({
transport: {
read: {
url: function () {
***omitted for privacy, but read works. the grid loads fine***
},
cache: false,
type: 'GET',
headers: {
'Accept': 'application/json; odata=verbose'
}
},
destroy: {
url: function (options) {
console.log(options);
console.log("destroy command called");
}
},
parameterMap: function (data, type) {
console.log(data);
console.log(type);
if (type == "destroy") {
// send the destroyed data items as the "models" service parameter encoded in JSON
return { models: kendo.stringify(data.models) }
}
}
},
pageSize: 10,
sort: {
field: "Modified",
dir: "desc"
},
filter: {
logic: 'and',
filters: [{
field: 'State',
operator: 'eq',
value: 'Submitted'
}]
},
error: function (e) {
kendo.alert(e.errors);
},
schema: {
errors: "error",
parse: function (response) {
console.log(response);
var data = [];
for (var i = 0, il = response.d.results.length; i < il; i++) {
var item = response.d.results[i];
//Create new fields to handle filtering by Date (instead of DateTime)
item.ModifiedFilter = new Date(new Date(item.Modified).setHours(0, 0, 0, 0));
item.CreatedFilter = new Date(new Date(item.Created).setHours(0, 0, 0, 0));
data.push(item);
}
return data;
},
total: function (response) {
return response.length;
},
model: {
id: 'Id',
fields: {
```
The dataSource.destroy.url handler should return the url which the grid will request for the destroy operation. As in your case the destroy.url handler does not return anything, the "" url is requested, which is equivalent to requesting your landing page, thus, HTML is returned.
If you do not intend to update the server on delete and just visually remove the row, simply define the destroy as a handler which does nothing.
e.g.
destroy: function (options) {
options.success(options.data.models);
}

Loop displaying undefined and I can't see where I've set it wrong

I'm looping through data from a .net web service through jsonp. Similar code works elsewhere but I can't see where i've gone wrong here.
The data is retreived through:
if (pageId === 'alerts') {
var Username = localStorage.getItem("Username");
var SessionKey = localStorage.getItem("SessionID");
console.log(Username);
console.log(SessionKey);
$.mobile.loading( 'show', { theme: "b", text: "Loading", textonly: false});
$.ajax({
crossDomain: true,
contentType: "application/json; charset=utf-8",
url: "http://redacted/GetData.asmx/GetLostAnimals",
data: {Username: Username, SessionKey: SessionKey },
dataType: "jsonp",
success: myAlerts
});
}
var lostSelectedPet = 0;
function myAlerts(data)
{
$("#alertsListMissingPets").empty();
$.mobile.loading( 'hide', { theme: "b", text: "Loading", textonly: false});
$.each(data, function(index) {
console.log(data[index].LostDate)
$("#alertsListMissingPets").append(" <li>"+ data[index].AnimalKey + " <span class=\"ui-li-count\">12</span></li>");
});
$("#alertsListMissingPets").listview('refresh');
}
$(document).on('click', '#alertsListMissingPets li a', function(){
localStorage.setItem("lostSelectedPet", $(this).attr('data-custom'));
editingId = $(this).attr('data-custom');
});
The json returned is like:
callback(
{
AnimalKey: "f152e1c6baca181d9f3ca1f18c91cc41f23fc122545d9c8bff9f4cb2ea449874",
LostDate: "11/06/2014 16:14:19",
FoundDate: "",
LostKey: "7560733274a7ca2ec43a85fcb9abd345fdc876acffac2b75ace7946035122fbd",
Resp: "OK"
}
)
However, this returns - It shows 5 items but theres only one result, the json above is the full response.
You are not looping over an array, you are looping over an object. You have 5 keys in the object, hence why there is 5 rows in the output.
Change the response to be an array.
callback(
[{ //<-- added [
AnimalKey: "f152e1c6baca181d9f3ca1f18c91cc41f23fc122545d9c8bff9f4cb2ea449874",
LostDate: "11/06/2014 16:14:19",
FoundDate: "",
LostKey: "7560733274a7ca2ec43a85fcb9abd345fdc876acffac2b75ace7946035122fbd",
Resp: "OK"
}] //<-- added ]
)

syntax error jquery handle json

Firebug says that there's a syntax error near:
if (json['name'] !="")
But I still can't find it. This is part of a long poll script that hangs until the server sends a response. When the server response is empty, it throws the error near if (json['name'] !="")
var timestamp=null;
function waitForMsg(){
$.ajax({
type: "GET",
url: "auth/classes/getdata.php?id="+6,
async: true,
cache: false,
success: function(data){
var json=eval('('+data+ ')');
if (json['name'] !=""){
if(json['type'] ==1){
$.notification({
content: json['name']+" liked a post",
showTime: true,
icon: '8',
timeout: 10000,
click: function() {
window.location.href = "http://www.test.com/posts.php?post="+json['post'];
}
});
}
if(json['type'] ==2){
$.notification({
content: json['name']+" disliked a post",
showTime: true,
icon: 'Y',
timeout: 10000,
click: function() {
window.location.href = "http://www.test.com/posts.php?post="+json['post'];
}
});
}
if(json['type'] ==3){
$.notification({
content: json['name']+" commented a post",
showTime: true,
icon: 'i',
timeout: 10000,
click: function() {
window.location.href = "http://www.teest.com/posts.php?post="+json['post'];
}
});
}
}
setTimeout("waitForMsg()",1000);
},
error: function(XMLHttpRequest,textStatus,errorThrown) {
// alert("error: "+textStatus + " "+ errorThrown );
setTimeout("waitForMsg()",15000);
}
});
}
$(document).ready(function() {
waitForMsg();
});
When the server response is empty, it throws the error near if (json['name'] !="")
So check to see if there is data
if(!data || !data.length) {
return;
}
var json=eval('('+data+ ')');
Modern day browsers support JSON.parse() and also jQuery will automtically do this for you if you return the correct content type from the server.
Why don't you use "dataType: 'json'" as an attribute of you ajax call? That would create a json object from the response and you can work directly with that variable.
$.ajax({
type: "GET",
url: "auth/classes/getdata.php?id="+6,
async: true,
cache: false,
dataType: "json",
success: function(data){
var json=data; //or you can work directly with data
If you return an empty message from your server ("" instead of "{}"), it will trigger the "error" function of your ajax call, since it will throw a parse exception.
Hope this helps you.
Regards,
Marcelo

Error with javascript 500 Internal Server Error

I am getting this error when I look at the javascript console
POST (url of website) GetUserPass 500 (Internal Server Error).
A popup also says that there is an unexpected token >
I am guessing that these two things are related so does anyone know anything about them or have they seen this before?
Here is the javascript code. The project is built in visual studio 2013.
<script type="text/javascript" src="../assets/plugins/data-tables/jquery.dataTables.datesorting.js"></script>
<script type="text/javascript">
var mvData = null;
var mvTable;
function GetDataSuccess(data, textStatus, XMLHttpRequest) {
$("#divMessage").html("").hide();
$("#userPassTable").show();
mvData = data.d;
mvTable.fnClearTable();
mvTable.fnAddData(data.d);
}
function GetDataError(XMLHttpRequest, textStatus, errorThrown) {
try {
var obj = jQuery.parseJSON(XMLHttpRequest.responseText);
$("#divMessage").html("An error occured: " + obj.Message + "<br>Exception Type: " + obj.ExceptionType).show();
}
catch (ex) { alert(ex.message); }
}
function logBodyOnLoad() {
$.ajax({
type: "POST",
url: "UserPass.aspx/GetUserPass",
data: JSON.stringify({}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: GetDataSuccess,
error: GetDataError
});
mvTable = $('#userPassTable').dataTable(
{
"fnDrawCallback": function (oSettings) {
/* Need to redo the counters if filtered or sorted */
// if (oSettings.bSorted || oSettings.bFiltered) {
// for (var i = 0, iLen = oSettings.aiDisplay.length; i < iLen; i++) {
// $('td:eq(0)', oSettings.aoData[oSettings.aiDisplay[i]].nTr).html(i + 1);
// }
// }
},
"aoColumns":
[
{ "sTitle": "Vendor", sClass: "left_align" },
{ "sTitle": "Username", sClass: "left_align" },
{ "sTitle": "Password", sClass: "left_align" }
],
"iDisplayLength": 1000,
"aaData": [["", "", ""]],
bPaginate: false,
bFilter: true,
bSort: false,
bJQueryUI: true,
bAutoWidth: false
});
}
$(document).ready(logBodyOnLoad);
</script>
I am wondering if the "....aspx/GetUserPass" the slashed portion is causing this problem - sure it should not be a query string value?
This is a server-side error, which means you need to check your error logs on the server to see what is going on. If you don't have logging enabled (recommend ELMAH, very easy to plug in via NuGet) then two ways you can see what is going on:
1 - If you don't have additional data you are posting to the page, then the easiest is to just browse to the page by itself, localhost:xxx/UserPass.aspx/GetUserPass
2 - If you do have unique data you are posting and need to see the results with that specific data, then use Chrome - open the debugger tools (F12) take a look at the Network tab and it will show the request to the server, select it and click the "response" tab to see the detail it spits out. Should be the ASP.NET error HTML when you can parse through and hopefully help figure out what is going on.
Hope this helps get you further down the road!

$.done() code gets executed before $.when()

In my project I m using 2 versions of JQuery.js, so I resolved the conflict using $.noConflict() for my latest version of JQuery to variable named jq172. Now I have used jq172.when().done()construct to show loading status image until all ajax request are processed completely. The code is as follows.
jq172.when(
DisplayPOXOrderStatistics(fromDate, toDate),
DisplayPOXCompletedOrdersData(fromDate, toDate),
DisplayPOXCompletedOrderPieChart(fromDate, toDate),
DisplayCurrentYearlyTrends())
.done(function (a1,a2,a3,a4)
{
$("#loading").hide();
});
where functions in the jq172.when() are coded as follows,
function DisplayPOXOrderStatistics(fromDate, toDate) {
return $.ajax({
type: "POST",
url: '#Url.Action("DisplayPOXOrderStatistics", "Home")',
dataType: "json",
data: { FromDate: fromDate, ToDate: toDate },
success: function (data) {application code.....}
});
}
function DisplayPOXCompletedOrdersData(fromDate, toDate) {
return $.ajax({
type: "POST",
url: '#Url.Action("DisplayPOXCompletedOrders", "Home")',
data: { FromDate: fromDate, ToDate: toDate },
dataType: "json",
success: function (data) { some code....}
});
}
& rest 2 functions are coded in the same way as above
Now my code in .done() to hide loading image dive should be executed after all 4 ajax call is finished, but currently it gets executed immediately after function call is dispatched. Can anybody figure out the problem in my code.
Thanks in Advance...
Here is the definition of rest 2 functions..
function DisplayPOXCompletedOrderPieChart(fromDate, toDate) {
return $.ajax({
type: "POST",
url: '#Url.Action("POXCompletedOrderPieChart", "Home")',
data: { FromDate: fromDate, ToDate: toDate },
dataType: "json",
success: function (data) {
$('#POXCompletedOrdersPie').empty();
var dataSet = [];
var isDataAvailable = false;
for (var i = 0; i < data.length ; i++) {
var newElement = { label: data[i].Name, data: parseFloat(data[i].ColumnValue), color: Color[i] };
dataSet.push(newElement);
if (newElement.data > 0)
isDataAvailable = true;
}
if (dataSet.length != 0 && isDataAvailable) {
$.plot($("#POXCompletedOrdersPie"), dataSet, {
series: {
pie: {
show: true
}
},
legend: {
show: false
}
});
}
else {
$("#POXCompletedOrdersPie").empty();
$("#POXCompletedOrdersPie").append("<html><p> <b>" + "#Html.Raw(VirtuOxAdvDME.Dashboard_PieChart_POXCompletedOrder_NoData)" + "</b> </p><html>");
}
}
});
}
function DisplayCurrentYearlyTrends() {
$("#DisplayCurrentYear").html($('#selectCurrentYear option:selected').text());
return $.ajax({
url: '#Url.Action("DisplayCurrentYearlyTrends", "Home")',
data: { selectedCurrentYear: $('#selectCurrentYear option:selected').text() },
type: 'POST',
dataType: 'json',
success: function (data) {
var DataValues = [], TickData = [];
var i = undefined;
$.each(data, function (index, item) {
i = (index + 1) * 2;
DataValues.push({ data: [i, item.Value], color: Color[i] });
DataValues.push([i, item.Value]);
TickData.push([i, item.MonthName]);
});
$.plot($("#CurrentYearlyTrendsBar"), [{ data: DataValues, color: "#3D69AA" }],
{
series: { bars: { show: true } },
bars: {
barWidth: 1.5,
align: "center"
},
xaxis: {
ticks: TickData,
axisLabelUseCanvas: true,
labelAngle: -90,
},
yaxis: { axisLabelUseCanvas: true },
grid: { hoverable: true }
});
$("#CurrentYearlyTrendsBar").UseTooltip();
}
});
}
Probably your $.ajax calls (from the old jQuery version) do not return jqXHR objects which implement the Promise interface, a feature that was introduced with v1.5. when would see the objects as plain values then and resolve immediately.
To fix this, use jq172.ajax() instead, or use a (single) up-to-date jQuery and update your legacy code.
this is from the jquery site
in the multiple-Deferreds case where one of the Deferreds is rejected, jQuery.when immediately fires the failCallbacks for its master Deferred. Note that some of the Deferreds may still be unresolved at that point. If you need to perform additional processing for this case, such as canceling any unfinished ajax requests, you can keep references to the underlying jqXHR objects in a closure and inspect/cancel them in the failCallback.
check your ajax calls and make sure no one is getting rejected. You can do this in the
developers console->network tab
generally becomes accessible after pressing F12.

Categories