How to execute a function to update a json source - javascript

I have a Leaflet map that show some weather data from a Json source. I have already a function that update the data every x minutes by a setInterval function.
setTimeout(function () {
refreshId = setInterval(function () {
$.ajax({
method: 'get',
dataType: 'text',
url: 'myURLfile.json',
success: function (data) {
if (data) {
markers = [];
var withoutMarkers = data.slice(10);
markers = JSON.parse(withoutMarkers);
//console.log(markers);
replaceMarkers(currentFactor);
}
},
error: function (err) {
console.error('there is not date for today.', err)
}
})
}, 300000);
},10000)
}
What I would to do now is assign this funtion to a button to execute the refresh fuction manually.
Something like
L.easyButton( 'fas fa-cloud-sun-rain', function(){
myfunction()
}, 'Refresh', {
position: 'topright'
})
But I don't understand what I have to call exactely to do it.

Factor your fetch code out of setInterval and use your newly made function both in setInterval and your button definition.
Something like
function fetchData() {
$.ajax({
method: 'get',
dataType: 'text',
url: 'myURLfile.json',
success: function (data) {
if (data) {
markers = [];
var withoutMarkers = data.slice(10);
markers = JSON.parse(withoutMarkers);
//console.log(markers);
replaceMarkers(currentFactor);
}
},
error: function (err) {
console.error('there is not date for today.', err)
}
});
}
// setup your interval
setInterval(fetchData, 300000);
// setup your button
L.easyButton( 'fas fa-cloud-sun-rain', fetchData, 'Condizioni', {
position: 'topright'
})

Related

jQuery wait for .each to finish and run ajax call

I have the following code:
var allChecks = [];
$('input[type=text]').each(function () {
var key = $(this).attr("id");
allChecks[key] = [];
}).promise()
.done(function () {
$('input[type=checkbox]').each(function () {
if (this.checked) {
var ref = $(this).attr('id');
$('.' + ref).each(function () {
allChecks[ref].push({
amount: $("#" + ref).text()
});
});
} else {
allChecks[ref].push({
amount: 0.00
});
}
}).promise()
.done(function () {
$.ajax({
cache: false,
type: 'POST',
data: {
allChecks: allChecks
},
url: '/process',
beforeSend: function () {
console.log("Processing your checks please wait...");
},
success: function (response) {
console.log(response);
},
error: function () {
console.log("Error");
}
});
});
});
My Ajax call runs but I see no data passed as parameters, like if the array allChecks is empty. As JavaScript runs synchronously, I'm expecting that whatever I place after each() will not run until each() is complete, so the Ajax call should run fine and nor give me no data passed as if the array allChecks is empty. Any help or solution on this would be appreciated. Thanks.

Close modal in ajaxStop

I have the following code:
var menuButtonClick = {
onReady: function () {
$(document).on('click', '.menu-button', function () {
menuButtonClick.clickedButton($(this).html());
});
},
clickedButton: function (val) {
switch (val) {
case 'CheckModelBank':
modelBankHandler.get();
break;
}
}
}
var modelBankHandler = (function () {
var get = function () {
var selectedCellData = handsonTable.selectedCellData.get();
var webGrid = handsonTable.WebGrid.get();
$.ajax({
type: 'POST',
url: "http://localhost:56292/api/Data/CheckModelBank",
data: { "": selectedCellData },
success: function (response) {
if (response != null) {
serverResult = JSON.parse(response);
printModelBank(serverResult, webGrid);
}
},
error: function (jqXHR, textStatus, errorThrown) {
if (textStatus == "error") {
modalHandler.printErrorModal();
}
}
});
}
var printModelBank = function (serverResult, webGrid) {
///
}
return {
get: get
}
})();
var fileHandler = {
onReady: function () {
var documentType = "";
$('.upload-file').click(function () {
$('[data-remodal-id=documentModal]').remodal().open();
});
$('.document-option').click(function () {
//Need to get the type of document the user is going to work with so we can parse the document correctly to the webgrid
documentType = $(this).html();
$('#fileUpload').click();
});
$('#fileUpload').change(function () {
fileHandler.upload(documentType);
});
$('.save-to-excell').click(fileHandler.saveDocument);
},
upload: function (documentType) {
var formData = new FormData();
var totalFiles = document.getElementById("fileUpload").files.length;
for (var i = 0; i < totalFiles; i++) {
var file = document.getElementById("fileUpload").files[i];
formData.append("fileUpload", file);
}
$.ajax({
type: 'post',
url: 'http://localhost:59973/Home/Upload',
data: formData,
dataType: 'json',
contentType: false,
processData: false,
success: function (response) {
jsonData = JSON.parse(response.data);
if (jsonData != null) {
if (documentType == "Infolog") {
fileHandler.printDocument(jsonData); //This is used for pickinglist and infolog
} else {
var webGrid = handsonTable.WebGrid.get();
webGrid.loadData(jsonData);
}
}
},
error: function (error) {
if (textStatus == "error") {
modalHandler.printErrorModal();
}
}
});
},
}
$(document).ready(function () {
handsonTable.init();
menuButtonClick.onReady();
fileHandler.onReady();
buttonClicks.onReady();
}).ajaxStart(function () {
$('[data-remodal-id=modalAjax]').remodal().open();
}).ajaxStop(function () {
$('[data-remodal-id=modalAjax]').remodal().close();
});
When I upload a file (fileHandler), the modal shows during ajaxStart and closes on ajaxStop. However, If I click on a button in my menu (menuButtonclick) which trigger my modelBankHandler function, the modal shows during ajaxstart, but does not close on ajaxStop.
Why? All the data are retrieved as expected in my modelBankHandler, so why does not the modal closes?
If you have pressed F12 in the browser and looked at the console you would probably have found an error there. This video might help you to figure out basic problems yourelf.
I think printModelBank might throw an error, if the success or error functions throw an error then jQuery crashes and does not execute the ajaxStop handler:
$(document)
.ajaxStart(function () {
console.log("open model");
}).ajaxStop(function () {
console.log("close model");
});
$.ajax({
type: 'GET',
url: "/none",
data: {},
success: function (response) {
console.log("success");
throw new Error("now stop won't execute");
},
error: function (jqXHR, textStatus, errorThrown) {
console.log("error");
throw new Error("now stop won't execute");
}
});
You could solve this by having success and error as promise handlers, errors in promise handlers should not crash jQuery (but it does):
$(document)
.ajaxStart(function () {
console.log("open model");
}).ajaxStop(function () {
console.log("close model");
});
$.ajax({
type: 'GET',
url: "/none",
data: {}
})
.then(
response => {
console.log("success");
throw new Error("now stop won't execute");
},
(jqXHR, textStatus, errorThrown) => {
console.log("error");
throw new Error("now stop won't execute");
}
);
You could try native promises (jQuery still doesn't get promises right) and have it not crash on error in handler:
$(document)
.ajaxStart(function () {
console.log("open model");
}).ajaxStop(function () {
console.log("close model");
});
Promise.resolve()
.then(_ =>
$.ajax({
type: 'GET',
url: "/none",
data: {}
})
)
.then(
response => {
console.log("success");
throw new Error("now stop WILL execute");
},
(jqXHR, textStatus, errorThrown) => {
console.log("error");
throw new Error("now stop WILL execute");
}
);
IE does not support native promises so you will need a polyfill or try babel with ES2016

How do I make a function call execute first before executing subsequent codes? [duplicate]

This question already has an answer here:
How do I return the response from an asynchronous call?
34 answers
I am trying to learn JS by building a random Quote Machine but this problem has been bugging me. I saw the other answers but I really couldn't understand them due to lack of context. Any help will be appreciated. The code is:
$(document).ready(function () {
$("#btn").click(function () {
getQuote(); //This should execute first, then the next lines
var quoteData = jSonify();
var quote = quoteData[0];
var author = quoteData[1];
console.log(quote);
console.log(author);
console.log("Button Clicked");//This Should execute last.
});
//Get them quotes
function getQuote() {
$.ajax({
url: 'https://andruxnet-random-famous-quotes.p.mashape.com/?cat=famous',
type: 'GET',
data: {},
datatype: 'json',
success: function (data) { jSonify(data); },
error: function (err) { alert(err); },
beforeSend: function (xhr) {
xhr.setRequestHeader("X-Mashape-Authorization", "qKPbfOzWKemsh2qi30QgbOA1WufXp1ok1NsjsnAkvh6yVJfaAk");
}
});
}
//Convert to jSon
function jSonify(rawData) {
var jSonified = jQuery.parseJSON(rawData);
var quote = jSonified.quote;
var author = jSonified.author;
console.log(quote);
console.log(author);
return [quote, author];
}});
getQuote() won't be done by the time JavaScript runs the next line, var quoteData = jSonify();. This is because it has a $.ajax call inside of it, which could take a long time to complete.
getQuote won't be done until the success method in the $.ajax method is called.
So what you need to do is pass a callback into getQuote, like so:
$("#btn").click(function () {
getQuote(function() {
var quoteData = jSonify();
var quote = quoteData[0];
var author = quoteData[1];
console.log(quote);
console.log(author);
console.log("Button Clicked");
});
});
//Get them quotes
function getQuote(done) {
$.ajax({
url: 'https://andruxnet-random-famous-quotes.p.mashape.com/?cat=famous',
type: 'GET',
data: {},
datatype: 'json',
success: function (data) { jSonify(data); done(); }, // Call the callback!
error: function (err) { alert(err); },
beforeSend: function (xhr) {
xhr.setRequestHeader("X-Mashape-Authorization", "qKPbfOzWKemsh2qi30QgbOA1WufXp1ok1NsjsnAkvh6yVJfaAk");
}
});
}
The callback will only be called once the ajax has actually finished. Once it's called, the rest of the computation will take place.
you can embed later to be called statements inside ajax success
$(document).ready(function () {
$("#btn").click(function () {
getQuote(); //This should execute first, then the next lines
});
//Get them quotes
function getQuote() {
$.ajax({
url: 'https://andruxnet-random-famous-quotes.p.mashape.com/?cat=famous',
type: 'GET',
data: {},
datatype: 'json',
success: function (data) {
var quoteData = jSonify(data);
var quote = quoteData[0];
var author = quoteData[1];
console.log(quote);
console.log(author);
console.log("Button Clicked");//This Should execute last.
},
error: function (err) { alert(err); },
beforeSend: function (xhr) {
xhr.setRequestHeader("X-Mashape-Authorization", "qKPbfOzWKemsh2qi30QgbOA1WufXp1ok1NsjsnAkvh6yVJfaAk");
}
});
}
//Convert to jSon
function jSonify(rawData) {
var jSonified = jQuery.parseJSON(rawData);
var quote = jSonified.quote;
var author = jSonified.author;
console.log(quote);
console.log(author);
return [quote, author];
}});

how to transform function to setTimeout

I'm using setInterval for now, but wish to use setTimeout.
$.when(
data['layout'] = "getMessages",
data['limit'] = limit,
fetchMsg(data,'[data-messages]',{"background-color":"#fff"})
).then(
setInterval(function(){
data['lastupdate'] = localStorage.lastupdate;
data['layout'] = "getNewMessages",
fetchMsg(data, '[data-body-new]',{"background-color":"#b4eeb4"});
}, 1000)
);
//the function
function fetchMsg(info, container, messageStyle){
$.ajax({
method: "POST",
url: window.root+"/index.php",
"data": info,
error: function() {
alert('error');
},
success: function(result) {
..........
}
});
I tried below but it doesn't work:
setTimeout(function(){
data['lastupdate'] = localStorage.lastupdate;
data['layout'] = "getNewMessages",
fetchMsg(data, '[data-body-new]',{"background-color":"#b4eeb4"});
}, 1000)
//the function
function fetchMsg(info, container, messageStyle){
$.ajax({
method: "POST",
url: window.root+"/index.php",
"data": info,
error: function() {
alert('error');
},
success: function(result) {
..........
},
complete:fetchMsg
});
I won't fix your code for you but here is a basic idea of going from an interval to a setTimeout.
Firstly, make your 'interval' equal to a variable.
var init = setInterval(doFunc,1000);
Later when you want to make the change:
clearInterval(init);
and then to set Timeout just do:
setTimeout(doFunc);
And thats basically it.

Replace ajax error and success functions with alternates passed to parent function

I have written the following JavaScript class:
var DbObject = Class.extend({
init: function(classname, id){
// do some init stuff
},
send: function(isError){
if(isError){
// do something else
}
else if(!uploading){ // global
var obj =$.parseJSON(JSON.stringify(this));
$.ajax({
type: "POST",
dataType: "json",
url: "ajaxManager.php",
data: {data:obj},
success: function(response) {
response.success=true;
if(response.callback) window[response.callback](response);
console.log(response);
},
error: function(xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
}
});
}
else{
console.log('waiting....');
var $this =this;
setTimeout(function(){$this.send(); }, 2000);
}
}
});
Right now, I use the class like this:
var object = new DbObject('PageSettings', rowId);
object.send();
I'd like to be able to also use it like this:
var object = new DbObject('PageSettings', rowId);
object.send(false, {
success: function (response) {
// some alternate code to run instead of the ajax `success: function`
},
error: function (xhr, status, error) {
// some alternate code to run instead of the ajax `error: function`
}
});
Where the { success: //...., error: //...} supplied in the call to .send() should replace the { success: //...., error: //...} in the ajax call it makes.
What would be the proper way to accomplish this?
This is a complete natural for promises. All you have to do is return the promise from the ajax call and your caller can then just use the promise directly without having to know what happened internally:
var DbObject = Class.extend({
init: function (classname, id) {
// do some init stuff
},
send: function (isError) {
if (isError) {
// handle synchronously, but still return a promise so
// the caller gets the same behavior
$(someSelector).show();
return $.Deferred().resolve(false).promise();
} else if (!uploading) { // global
var obj = $.parseJSON(JSON.stringify(this));
return $.ajax({
type: "POST",
dataType: "json",
url: "ajaxManager.php",
data: {
data: obj
}
});
} else {
console.log('waiting....');
var self = this;
return $.Deferred(function(def) {
// now set up delayed execution
setTimeout(function () {
def.resolve();
}, 2000);
}).then(function() {
// link this into the existing promise chain
return self.send();
});
}
}
});
And, sample usage:
var db = new DbObject('PageSettings', rowId);
db.send().then(function (result) {
// success here
}, function (err) {
// error here
});
Change the send function like this:
send: function (isError,handlers) {
if (!handlers) handlers = {};
if (!uploading) {
var obj = $.parseJSON(JSON.stringify(this));
$.ajax({
type: "POST",
dataType: "json",
url: "ajaxManager.php",
data: {
data: obj
},
success: handlers.success || function (response) {
....
},
error: handlers.error || function (xhr, status, error) {
....
}
});
} else {
....
}
}

Resources