Leaflet load data and edit feature properties on mouse click - javascript

I am loading map data from a GeoJSON file and attaching a click event for every polygone. on click, the script should fetch data from the server AND modify one of the clicked polygon's properties. i.e:
function onClick(e) {
var status = e.target.feature.properties.ACCESS;
$.ajax({
url: "http://127.0.0.1:8080/?&u=x&p="+e.target.feature.properties.ID_PARCELL,
dataType: 'jsonp',
type: 'GET',
success: function(data) {
status = data.status;
e.target.feature.properties.ACCESS = data.status;
e.target.bindPopup("Owner: <b>"+ data.status +"</b>").openPopup();
},
error: function(data){console.log(data)}
});
e.target.feature.properties.ACCESS = status;
map.fitBounds(e.target.getBounds());
}
But since the success function is an callback (synchronous or not, it doesn't really matter), I am not able to get back to the original event source (namely e) so I could modify one of its properties.
My question is: How can I get back to the event source after loading this data? Is there any generic Javascript way? If not, is there any way I can query the GeoJSON layer by feature ID ? (=> I can therefore send the feature ID in the ajax call, and simply get it back with the response)

The solution is to send the desired variable e to the anonymous function by using the context entry:
function onClick(e) {
var status = e.target.feature.properties.ACCESS;
$.ajax({
url: "http://127.0.0.1:8080/?&u=x&p="+e.target.feature.properties.ID_PARCELL,
dataType: 'jsonp',
context: e,
type: 'GET',
success: function(data) {
status = data.status;
e.target.feature.properties.ACCESS = data.status;
e.target.bindPopup("Owner: <b>"+ data.status +"</b>").openPopup();
},
error: function(data){console.log(data)}
});
e.target.feature.properties.ACCESS = status;
map.fitBounds(e.target.getBounds());
}

You'r using the same event name 'e' on both Click and success functions. Try to change one of them. ie
function onClick(e) {
var status = e.target.feature.properties.ACCESS;
$.ajax({
url: "http://127.0.0.1:8080/?&u=x&p="+e.target.feature.properties.ID_PARCELL,
dataType: 'jsonp',
type: 'GET',
success: function(data, evt) {
status = data.status;
e.target.feature.properties.ACCESS = data.status;
e.target.bindPopup("Owner: <b>"+ data.status +"</b>").openPopup();
},
error: function(data){console.log(data)}
});
e.target.feature.properties.ACCESS = status;
map.fitBounds(e.target.getBounds());
}
now you can change the initial event 'e' properties when the result is returned.
Hope this helps.

Related

Flask can read a POST datum but not another

So I'm trying to pass some data from my front-end to the back-end. It is the user's nickname and the location of the user. But while I can read and print out the nickname in flask, I always get None when I want to read the location value in the backend. I'm not really sure why this is happening, since I can actually print the location value in the javascript console before passing it to the backend and everything is allright. I would really appreaciate any help :)
This is my relevant code:
JS
$(document).on("submit", "#get_nickname", function(e)
{
var coords = {};
//Get location
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(function(loc){
var latlng = loc.coords.latitude + "," + loc.coords.longitude;
String(latlng);
latlngContainer = latlng;
coords.latlng = latlngContainer;
});
}
console.log(coords);
e.preventDefault();
$.ajax({
type: "POST",
url: "/add_address",
data: {
nickname:$("#nickname").val(),
location: coords
},
success: function()
{
set_address_cookie(31);
session_memory();
add_address_toggle();
}
})
});
PYTHON
#app.route("/add_address", methods=['POST'])
def add_address():
nickname = request.form.get("nickname")
location = request.form.get("location")
print(f"Hi {nickname}, you are here {location}")
return "", 201
Here are some pictures:
my chrome console log with everything allright
the error shown on flask
Location is being dropped because it's an object. Try to send the data as json however you will have to modify your flask app to accept it.
$.ajax({
type: "POST",
url: "/add_address",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({
nickname:$("#nickname").val(),
location: coords
}),
success: function()
{
set_address_cookie(31);
session_memory();
add_address_toggle();
}
});
EDITS:
I just noticed geolocation.getCurrentPosition callback is asynchronous meaning it executes later when the ajax already happened. You have to wait for it to finish executing before posting. I am not sure what environment you're working from but I re-wrote your JS try it and see if it works for you.
$(document).on("submit", "#get_nickname", function(e)
{
e.preventDefault();
function addAddress(data){
$.ajax({
type: "POST",
url: "/add_address",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(data),
success: function()
{
set_address_cookie(31);
session_memory();
add_address_toggle();
}
});
}
var data = { nickname: $("#nickname").val() }
var coords = {};
//Get location
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(function(loc){
var latlng = loc.coords.latitude + "," + loc.coords.longitude;
String(latlng);
latlngContainer = latlng;
coords.latlng = latlngContainer;
data.coords = coords;
addAddress(data); //submit with coords
}, function(){
addAddress(data); //submit without coords when failed to get coords
});
} else addAddress(data); //submit without coords when not supported
});

The GET request to make must change with button ID clicked

I am new to JQUERY and AJAX.
I need to make a get request to the git search api based on the topic the user chooses, i.e. if the user chooses clicks the button named ruby, I want to make a request to git for the top 10 python apis, similarly if he clicks a button named php i want to display repos of php.
To achieve this i created 2 ajax functions and called the respective ajax function at the button click.
<button id="ruby" onclick="startAjax();" class="btn btn-outline-dark">Java</button>
<button id="php" onclick="startAjax1();" class="btn btn-outline-dark">ios</button>
then,
function startAjax(){
$.ajax({
headers:{ "Content-Type":"application/json","Accept": "application/json"},
type:'GET',
url:'https://api.github.com/search/repositories?q=repos+topic:ruby&sort=stars&order=desc&per_page=10', });
function startAjax1(){
$.ajax({
headers:{ "Content-Type":"application/json","Accept": "application/json"},
type:'GET',
url:'https://api.github.com/search/repositories?q=repos+topic:ios&sort=stars&order=desc&per_page=10',});
This requires me to write as many ajax calls as buttons are there, is there a better way to do this? Can i use the id of the button and change the get url accordingly?
Thank you:)
What you always have to do is to look what are the differences in a function, what is variable. Everything variable should be - you guessed it - a variable. :-)
So in your case, it would be simple to use the id (or a data-attribute). To do this, try something like
$('button').on('click', function() {
$.ajax({
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
type: 'GET',
url: 'https://api.github.com/search/repositories?q=repos+topic:' + $(this).attr(“id”) + '&sort=stars&order=desc&per_page=10',
}).then(s => console.log(s));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="ruby" class="btn btn-outline-dark">Java</button>
<button id="php" class="btn btn-outline-dark">ios</button>
Also, don't use inline javascript. Better assign a proper event listener and handler like demonstrated above.
Use data attributes
<button class="btn btn-outline-dark ajax-button" data-url="https://api.github.com/search/repositories?q=repos+topic:ruby&sort=stars&order=desc&per_page=10">Ruby</button>
<button class="btn btn-outline-dark ajax-button" data-url="https://api.github.com/search/repositories?q=repos+topic:ios&sort=stars&order=desc&per_page=10">ios</button>
Then send the data attribute to a single function.
function startAjax(url){
$.ajax({
headers: {
"Content-Type":"application/json",
"Accept": "application/json"
},
type: 'GET',
url: url
});
$(document)ready(function(){
$(".ajax-button").click(function(event){
var url = $(event.target).data("url");
startAjax(url);
});
});
I usually use this ajax delegation logic to implement jquery/ajax unless I need more control over the request queue, in which case I'll use the $.when.apply() method posted below.
As far as your question about different URL's for different buttons, you can use the data attribute on the button element to store the URL's and access via the jquery .data() function.
Ajax Delegation
(function($){
$(function(){
//Usage Example
var inputString = $("#myInput").val();
var inputNumber = $("#myInteger").val();
var data = {inputString: inputString, inputNumber : inputNumber};
$('parent').on('click', 'button', delegateAjax('js/myAjax.php', data, 'POST');
});
function delegateAjax(url, data, responseType, dataType, callback) {
function successHandler() {
console.log("Ajax Success");
};
function failureHandler(xhr, status, error) {
console.log("Ajax Error");
console.log(status);
console.log(error);
console.dir(xhr);
};
function handler404(xhr, status, error) {
console.log("404 Error");
console.log(status);
console.log(error);
console.dir(xhr);
};
function handler500(xhr, status, error) {
console.log("500 Error");
console.log(status);
console.log(error);
console.dir(xhr);
};
url = typeof url !== 'undefined' ? url : 'js/ajaxDefault.php';
data = typeof data !== 'undefined' ? data : new Object();
responseType = typeof responseType !== 'undefined' ? responseType : 'GET';
dataType = typeof dataType !== 'undefined' ? dataType : 'json';
callback = typeof callback !== 'undefined' ? callback : 'callback';
var jqxhr = $.ajax({url: url, type: responseType, cache: true, data: data, dataType: dataType, jsonp: callback,
statusCode: { 404: handler404, 500: handler500 }});
jqxhr.done(successHandler);
jqxhr.fail(failureHandler);
};
})(jQuery);
Ajax Request Queue
//Set this var to max requests in queue.
var ajaxMax = 5;
var ajaxActive = 0;
$( document ).ajaxStart(function() {
ajaxActive++;
document.ajaxRunning = ajaxActive > 0;
document.ajaxQueueFull = ajaxActive > ajaxMax;
});
$(document).ajaxStop(function() {
ajaxActive--;
document.ajaxRunning = ajaxActive > 0;
document.ajaxQueueFull = ajaxActive > ajaxMax;
}
var request = $.ajax({
type: 'POST',
url: 'someurl',
success: function(result){}
});
while(request === null && (request.readyState < 1 || request.readyState > 4)) {
if (document.ajaxQueueFull) {
//abort existing requests
$.each(request as v) {
v.abort();
}
}
pendingAjax.push(request);
}
$.when.apply($, pendingAjax).done( successCallback ).fail( failCallback)

how do i use AJAX in jQuery on multiple elements?

(function($) {
$('.myclass').each(function(){
$(function() {
$.ajax({
url: "myPHP.php?app",
method: 'GET',
complete: function(jqXHR, textStatus) {
var response = JSON.parse(jqXHR.responseText);
$('.myclass').html(response.app);
}
});
});
});
})(jQuery);
i have multiple instances of myclass and I want each instance to be replaced with response.app but it doesnt happen.
What am i missing?
With your code, on every response from the server, all of your .myclass will be modified. You could try something like this:
$('.myclass').each(function() {
var $elem = $(this); // <-------------- Save the element for the ajax callback
$.ajax({
url: "myPHP.php?app",
method: 'GET',
complete: function(jqXHR, textStatus) {
var response = JSON.parse(jqXHR.responseText);
$elem.html(response.app); // <-------------- Use it
}
});
});
By the way, the requested URL seems to be the same for each call, with no specific parameter. If that's the case in your real code, then you only need to make one request (no .each()), and apply the result to all of your elements:
$.ajax({
url: "myPHP.php?app",
method: 'GET',
complete: function(jqXHR, textStatus) {
var response = JSON.parse(jqXHR.responseText);
$('.myclass').html(response.app);
}
});
jquery´s html function handles the replacement off all occurrence of myclass
so you just have to make the ajax call and pass the response
$.ajax({
url: "myPHP.php?app",
method: 'GET'
}).done(function(response){
$('.myclass').html(response.app)
});

Javascript function being called again while it is still running

I have a javascript function that is called when the user clicks on a button and performs an AJAX query that adds some data to my database. However, I've been getting complaints that a lot of data hasn't been getting through, and I've isolated the problem to be the time between clicks. When they wait long enough between clicks, the data always gets through, but if they don't wait long enough it's a crapshoot.
So I'm pretty much settled that the problem is that the javascript function is being called again while it is already running, which I shouldn't allow. Is there a way I can lock the user's browser at the beginning of the function and unlock it at the end after the AJAX? I know this may irritate my users, but I can't see any other solution.
It's not totally necessary, but here's what my javascript function looks like:
function addtolist(thisform, sdata)
{
var scntDiv = $('#p_data');
var request = $.ajax({ async: false, url: "php_addtolist.php", type: "POST", data: {data:sdata}, dataType: "html" });
request.done(function(msg) { outdata = parseInt(msg); });
$(outdata).appendTo(scntDiv);
}
You can disable the button when the function is called, then re-enable it with the complete callback:
function addtolist(thisform, sdata)
{
$('#submit_btn').prop('disabled', true);
var scntDiv = $('#p_data');
var request = $.ajax({
async: false,
url: "php_addtolist.php",
type: "POST",
data: {data:sdata}, dataType: "html" },
complete: function() { $('#submit_btn').prop('disabled', false); }
);
request.done(function(msg) { outdata = parseInt(msg); });
$(outdata).appendTo(scntDiv);
}
Basically it seems like the outdata is async. the following should resolve.
function addtolist(thisform, sdata)
{
var scntDiv = $('#p_data');
var request = $.ajax({ async: false, url: "php_addtolist.php", type: "POST", data: {data:sdata}, dataType: "html" });
request.done(function(msg) {
outdata = parseInt(msg);
$(outdata).appendTo(scntDiv);
});
}

How to connect to the Parse Javascript API? (502 error)

I am building a chatroom-type app using the Parse Javascript API. The task is to get some data from Parse, display it, add user input to the messages, and send it right back to parse.
The problem is I am not being able to see the data from parse, and receive a 502 error. I am a bit newer to javascript, so any advice on how to accomplish this, or any mistakes you may see in my code, would be fantastic. I also commented out my code the best I could. Thanks for the help.
Here is my code;
$(document).ready(function(){
delete Chat.display;
delete Chat.send;
delete Chat.fetch;
var my_messages = $('ul.messages')
//fetches data from parse
var myChat = function() {
$.ajax({
url: "https://api.parse.com/1/classes/chats",
dataType: "json",
success: console.log("Success"),
function message(a) {
my_messages.append('<ul>' + a +'</ul>'); //adds ul 'text' to messages
};
});
};
myChat(); // call mychat
$('button.send').on('click', function() { // when user clicks send
// send post to
$.ajax({
type: "POST",
url: "https://api.parse.com/1/classes/chats",
data: JSON.stringify({text: $('input.draft').val()}), // stringify the text on value input.draft
function(message){
window.location.reload(1) //refresh every 3 seconds
});
});
});
</script>
you have syntax error in both of your success functions of $.ajax calls. In the first ajax call you have places console.log, which should be inside the success callback. In the second one u haven't even added success: callback.
Try below updated code
$(document).ready(function(){
delete Chat.display;
delete Chat.send;
delete Chat.fetch;
var my_messages = $('ul.messages');
var myChat = function() {
$.ajax({
url: "https://api.parse.com/1/classes/chats",
dataType: "json",
success:function message(a) {
console.log("Success")
$.each(a,function(i,item){
my_messages.append('<ul>' + item.username +'</ul>'); //adds ul 'text' to messages
});
}
});
};
myChat(); // call mychat
$('button.send').on('click', function() { // when user clicks send
// send post to
$.ajax({
type: "POST",
url: "https://api.parse.com/1/classes/chats",
data: JSON.stringify({text: $('input.draft').val()}), // stringify the text on value input.draft
success:function(message){
window.location.reload(1) //refresh every 3 seconds
}
});
});
});

Categories