Create a simple poll for an api page change - javascript

I have a java servlet which responds with a number in text/plain format. What I want to do is have another page run a script which polls this URL and triggers an alert window when the number there has changed from the first time it was loaded. I have little to no experience with javascript and so far have been unable to follow any of the long-polling tutorials I have found.
Basically, I need to start the poll on page load, remember what the first value retrieved was, and then trigger an alert window once the value changes.
This is what I have so far, however I believe I need to parse the data somehow. The URL returns a text/plain page with a number on it. That's it.
var initial = null;
function checkForMsg() {
$.ajax({
type: "GET",
url: URL_GOES_HERE,
dataType : "text",
async: true,
cache: false,
success: function(data) {
if (initial == null) {
initial = data
}
else if (initial != data) {
alert(data);
}
setTimeout('checkForMsg()', 12000);
},
error: function() {
setTimeout('checkForMsg()', 12000);
}
})
}
$(document).ready(function(){
checkForMsg();
});

Related

How to load function after ajax load all DOM elements

I have an issue with a function that should be loaded after all content is ready.
I have a massive ajax call 1700 line of code.
How my code works: php file getting data from 3 tables in my database and converting it to JSON. I opening the JSON file and creating 1 element for 1 database result.
For now, I have around 100 results but I will have around 1000 in the final step. So I create loading to put before the page will be loaded. But because the main content is created by js, sometimes my loading fade out 1-2 sec before content is loaded. I can use js or jquery. For now, I used something like that :
$(window).on ('load', function (){
setTimeout(function (){
$("#loading").fadeOut('slow');}, 1000)});
Execute the function once you received data through AJAX. Check the code snippet below
$.ajax({
url: '/URL/TO/CODE',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') //This is optional if you are using x-csrf-token validation of if u want to pass any header data
},
type: "post",
data: {
data:data //In case if you need to pass any data
},
dataType: 'json',
cache: false,
before:function(){
//Is you want to show any loader or anything while ajax is being executed.
},
success: function (response) {
//Once your ajax is success you can call your custom function to do things with the data
myCustomFunction();
},
error: function (res) {
console.log(res);
}
});
function myCustomFunction(){
//This to be executed when all data are filled by ajax and page is loaded
}
Hope this helps.
$(window).ready(function (){
setTimeout(function(){ $("#loading").fadeOut('slow'); }, 3000);
});

C# MVC Razor 5: location.href in an ajax call

I have a solution in my MVC project which allows me to show and/or hide a loading screen whenever I want to:
$("#divLoading").show();
$("#divLoading").hide();
This "divLoading" essentially contains the loading screen. Now this solution works fine most of the time; even if I want to use Ajax in order to show the loading screen when the script begins execution and hide it when the function is done. Something like:
$("#btnTreatData").click(function () {
$("#divLoading").show();
// Some stuff
$.ajax({
contentType: 'application/json; charset=utf-8',
url: '#Url.Action("TreatValidationData", "Article")',
type: "POST",
data: JSON.stringify({ listOfCheckedData: listOfCheckedData }),
success: function (result) {
$("#tableControl").html(result);
$("#divLoading").hide();
}
});
}
This works fine. However, there is one specific edge-case where I can't get this to work properly.
Essentially, this project uses a plugin named EEPlus (http://epplus.codeplex.com/) in order to export data into an XLS file. It's very practical for the user because they simply click on the button, and there's no redirection involved; when the file is done, the user is prompted to download it by the browser itself.
Essentially, my export method does something like this:
public void ExportListUsingEPPlus(string filter, string type)
{
// A boat load of data processing and formatting that isn't relevant here
// Once the work is done:
// Write in an Excel file
using (var memoryStream = new MemoryStream())
{
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", $"attachment; filename={filename}.xlsx");
excel.SaveAs(memoryStream);
memoryStream.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
}
You will notice this method doesn't return anything. It doesn't need to; in the View itself, it is called like this:
<li class="separator"><input value="Export xls" class="add" name="btn_submit" id="btn_excel" type="button" onClick="location.href='#Url.Action("ExportListUsingEPPlus", "Article", new { filter = #ViewBag.CurrentFilter, type="TEST"})'"></li>
Which is okay... except that if I try to use a loading screen for this, because exporting data can take a long while:
function exportWithLoadingScreen()
{
$("#divLoading").show();
$.ajax({
contentType: 'application/json; charset=utf-8',
url: '#Url.Action("ExportListUsingEPPlus", "Article", new { filter = #ViewBag.CurrentFilter, type = "TEST" })',
type: "POST"
}).complete(function (result) { $("#divLoading").hide();});
}
Ajax :
Doesn't proc a "success" event.
Doesn't proc a "failure" event.
Procs a "complete" event... but, of course, without location.href = '...', it doesn't actually do anything (the file is created in memory but the user is never prompted to download it).
If I try to use the same thing but caring about location.href, it procs the "complete" event far too early, possibly because it only cares when the redirection is complete, NOT when the method is done!
I really don't know what else I could try at this point, but it's so important to show a loading screen for this, because it really can take a long while.
Any ideas as to what else I could do? I'd appreciate it a lot!
EDIT: I'll be more precise and concise. This:
function exportWithLoadingScreen() {
$("#divLoading").show();
location.href = '#Url.Action("ExportListUsingEPPlus", "Article", new { filter = #ViewBag.CurrentFilter, type = "TEST" })';
$("#divLoading").hide();
}
Doesn't work, because all actions are simultaneous, so I have to use ajax. But this:
function exportWithLoadingScreen() {
$("#divLoading").show();
$.ajax({
contentType: 'application/json; charset=utf-8',
url: '#Url.Action("ExportListUsingEPPlus", "Article", new { filter = #ViewBag.CurrentFilter, type = "TEST" })',
type: "POST"
}).complete(function (result) { $("#divLoading").hide(); })
};
Doesn't work either, because location.href is NOT executed (=> user is not prompted for download). But THIS:
function exportWithLoadingScreen() {
$("#divLoading").show();
$.ajax({
contentType: 'application/json; charset=utf-8',
url: '#Url.Action("ExportListUsingEPPlus", "Article", new { filter = #ViewBag.CurrentFilter, type = "TEST" })',
type: "POST"
}).complete(function (result) { window.location.assign(result);})
};
Doesn't work, because the returned data is completely wrong (server error), because the ExportListUsingEPPlus method doesn't return anything.
EDIT EDIT: Edited question's title to refocus the question.
I think the confusion is made by the fact that you want to use an Ajax call, but also need to redirect the page.
Ajax is used to request data from the server back to the current page so that you can update the current page with the new data.
A redirect abandons the current page and replaces it with a new one entirely.
Here is another answer that explains it, with something that can simulate an Ajax request - but it still isn't an Ajax request if it is redirecting...
https://stackoverflow.com/a/9970672/4619012
You can get help from calling ajax events. Find it here https://api.jquery.com/Ajax_Events/

AJAX - Is there an on Data Receive Function?

I have a page that loads a lot of data from the database and writes it to the DOM.
Depending on the amount of records, this could take a good 30 seconds or so between receiving the data and printing it to the DOM.
I am curious if there is a way to detect once data has begun downloading / received from the AJAX call?
The reason I ask is I have a loading indicator (spinner gif) on the page that shows that something is happening.
I would like to be able to detect when data has begun downloading and change this to another message, kinda like "Step 2 of 2" so that the user knows it is progressing.
Step 1: On Document Ready, show loader: $('#loading').show();
Step 2: Trigger AJAX call to fetch data
$.ajax({
url: "api/fetchDashboard",
type: 'POST',
cache: false,
data: {
dashboardID: dashboardID
},
error: function(err) {
alert(err.statusText);
},
success: function(data) {
// Write data to the DOM here
// Once done, hide loader
$('#loading').hide();
}
});
Step 3: Write our data to the DOM and hide the loading indicator
My ask is that once we start receiving the data, detect that and change the loading indicator to something else to state that we have retrieved the data and its being prepared for viewing.
Is this possible to detect and trigger another function upon receiving? In the image above, you can see that it is downloading all the data and was thinking that once that counter started, it would be an indication that we have retrieved something back.
Update:
Per ask, this is how I am appending to the DOM, outside of the loop once all the rows have been concatenated.
var output = '',
$.ajax({
url: "api/fetchDashboardRender",
type: 'POST',
cache: false,
data: {
dashboardID: dashboardID
},
error: function(err) {
alert(err.statusText);
},
success: function(data) {
// Set our results as a variable
dashResults = data // Holds the dashboard results
// Loop over the core data
$(dashResults['data']['results']['data']).each(function() {
output += 'Table Row Data Here';
});
// Append the results to the DOM
$('[name=results]').empty().append(output);
}
});

Ajax request 'onError' handler

There is one feature on my site: delete without page refresh. The user just presses 'delete' and the browser will send Ajax-request. It will load 'delete' script with id parameter.
All work well. But it is not very good because of referential integrity of the database. For example, It is possible to delete street, where some people are living.
I want to upgrade my script. I want to add a check to delete script and don't let delete data if some 'people' are connected to 'street' table.
jQuery handler of button click:
$('body').on('click', '.deleteStreet', function()
{
var id = $(this).attr('id');
var hideMe = $(this).parent().parent();
var dataString = 'id=' + id;
if(confirm("Are you sure you want to delete street? It is possible some people living there!"))
{
$.ajax({
type: "GET",
url: "/index.pl?mode=streets&action=delete",
data: dataString,
cache: false,
success: function(e)
{
hideMe.hide();
}
});
return false;
}
});
It will call script anyway and now will delete data anyway. I can add some checks to delete script now and it wouldn't delete, but jquery script would work anyway and will hide table row anyway (because request was send ok, without 404, etc)
1) Is it possible to see delete script result and hide or not hide row depending on it? For example, it will return true or false, js script will catch it and show message about deleting or not deleting of data depending on it.
2) This problem caused by structure of my site. There are some switches on index.pl and load appropriate scripts loading depending on query (mode=street then load street.pl, mode=user then load users.pl etc). So it will show all data loaded before delete.pl script and it will be impossible to check script returned true or false.
Any help? :) Thank you!
P.S.: I am very sorry for my awful english.
You can have the result of your ajax call in the first parameter of the success callback. ex:
$.ajax({
type: "POST",
url: "/index.pl?mode=streets&action=delete",
data: dataString,
cache: false,
success: function(e)
{
if(e === '1'){
hideMe.hide();
}
}
});
try to log your result in the console for tests: console.log(e).
For deleting data you should use a POST request ( or DELETE but not supported by all browsers).
I dont know how your datas (streets) looks like but an other way could it be to return all your existing streets in a json object on the delete request result. And refresh all lines.

if Ajax request don't finish, html links can't click

I have a jquery ajax request in my website page, and every page i need to post this request to server to get the status. But it have a issue: after i open the page in browser, before this request return the data, my page all link can't works, they can't click.But it render normal. so anybody have a solution for that? such as: make the page load this script after page loaded or other.
$(function(){
var login_status;
$.ajax({
async:false,
url:<%= url(:login_status_header_session, :from => from_uri).to_json %>,
dataType:"html",
success:function(data, textStatus){
login_status = data;
}
});
if(login_status) {
$(".loginDetails p .login_status").html(login_status);
} else {
$(".loginWrapper").remove();
}
});
this is the login_status_header actin:
self.headers["Cache-Control"] = "no-cache, must-revalidate"
self.headers["Expires"] = "0" partial "session_header",
:format => "html"
First, remove the async:false, line. This way the interface will keep responding while the AJAX request is being processed. Second, move your checking of the result into the success function - otherwise it runs before the request finishes, and so login_status hasn't been set yet (and thus defaults to null, which is treated as false).
$(function(){
var login_status;
$.ajax({
url:<%= url(:login_status_header_session, :from => from_uri).to_json %>,
dataType:"html",
success:function(data, textStatus){
login_status = data;
if(login_status) {
$(".loginDetails p .login_status").html(login_status);
} else {
$(".loginWrapper").remove();
}
}
});
});
Without more information I can only guess, and my guess is that since you're using async: false, the interface is not responding. Is there a reason for doing the request synchronously? If not try removing async:false and see if that works.
Uhm... without examining your code in too much detail, if this is supposed to occur at soon as the page is loaded, why not just put it on the server side, and generate the proper HTML in the first place? i.e. do it with PHP or whatever you're using and forget the AJAX?

Categories

Resources