I’m having an html file location.html and a file with data location.data both on the same webserver in the same directory. the contens of location.data is always the current location data in the form
{"lat":"44.17027","lon":"15.595542","timestamp":"1723663819127","hdop":"2.394","altitude":"510.35","speed":"0.73396146"}
it is written via json_encode() in another php file.
Now I need to read this data in a javascript in location.html into an array to display it on a map via leaflet. (It has to be html)
I just can’t manage to get this done. I tried XMLHttpRequest() with no success. Would appreciate any other (elegant) method.
<script>
var locx = new XMLHttpRequest();
locx.open('GET', 'location.data');
locx.onreadystatechange = function () {
if (locx.readyState === 4 && locx.status === 200) {
var locationData = locx.responseText;
}
};
locx.send();
</script>
6
If the fetch works (and it should), then the rest will look like this
Working example using PHP to generate JSON
https://plungjan.name/SO/leafletjson
const showMap = data => {
const { lat, lon } = data;
// Initialize the map
const map = L.map('map').setView([lat, lon], 13); // 13 is zoom level
// Add OpenStreetMap tile layer
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap contributors'
}).addTo(map);
// Add a marker to the map at the fetched coordinates
L.marker([lat, lon]).addTo(map)
.bindPopup(`Location: [${lat}, ${lon}]`)
.openPopup();
};
showMap(data); // remove this line on your server and uncomment the fetch
/*
fetch('location.data') // or fetch('jsonGeneratingPHP.php')
.then(response => {
if (!response.ok) { // added more fine grained error handling
throw new Error(`Network response was not ok (status: ${response.status})`);
}
return response.json(); // Parse the JSON only if the response is ok
})
.then(showMap)
.catch(error => console.error('Error fetching the location data:', error));
*/
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<div id="map" style="height: 400px;"></div>
<script>
// delete this script on your server and uncomment the commented fetch
// test data, remove when fetch works
const data = { "lat": "44.17027", "lon": "15.595542", "timestamp": "1723663819127", "hdop": "2.394", "altitude": "510.35", "speed": "0.73396146" };
</script>
6
You should be using fetch()
to get the data via an HTTP GET request from the server and then parse the JSON into a JavaScript object. Then use the information in that object to display a marker on the map (or whatever you want to do) using leaflet.
Leaflet code part is based on mplungjan’s answer and was added later to give you a full answer including all relevant parts of the question.
(async() => {
async function fetchLocation(){
const mockedApiResponse = `{"lat":"44.17027","lon":"15.595542","timestamp":"1723663819127","hdop":"2.394","altitude":"510.35","speed":"0.73396146"}`
const response = await fetch("https://httpbin.org/post", {
method: "POST",
body: mockedApiResponse,
})
if (!response.ok) {
throw new Error(`Failed to fetch location.data with status code ${response.status}`);
}
const locationData = await response.json()
return locationData.json; // here I need to use .json since the HTTP Bin API returns more data, but this line will be unnecessary for you
}
function displayOnMap(location){
const { lat, lon: lng } = location;
// Initialize the map
const zoomLevel = 15;
const map = L.map("myMap")
.setView([lat, lng], zoomLevel);
// Add OpenStreetMap tile layer
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map);
// Add a marker for location
L.marker([lat, lng])
.addTo(map)
.bindPopup(`Coordinates: ${lat}, ${lng}`)
.openPopup();
}
const location = await fetchLocation();
displayOnMap(location);
})();
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<div id="myMap" style="height: 200px;"></div>
In fetchLocation()
above there is some stuff I just needed to include to get a working example here on this page (e.g. use POST instead of GET, to allow for the API to return the data I give it etc.). In your case you can just replace the implementation of this function with the code below:
async function fetchLocation(){
// assuming your file is within the web root otherwise change URL to match path where your file is stored
const response = await fetch("location.data");
if (!response.ok) {
throw new Error(
`Failed to fetch location.data with status code ${response.status}`
);
}
return await response.json();
}
You should also add some error handling using
try...catch
.
4